tapyrus 0.2.6 → 0.2.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (119) 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/.ruby-version +1 -1
  6. data/CODE_OF_CONDUCT.md +7 -7
  7. data/README.md +14 -17
  8. data/Rakefile +3 -3
  9. data/lib/openassets/marker_output.rb +0 -4
  10. data/lib/openassets/payload.rb +4 -10
  11. data/lib/openassets.rb +0 -2
  12. data/lib/schnorr/sign_to_contract.rb +51 -0
  13. data/lib/schnorr/signature.rb +3 -6
  14. data/lib/schnorr.rb +14 -9
  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/ecdsa.rb +4 -4
  26. data/lib/tapyrus/ext/json_parser.rb +1 -4
  27. data/lib/tapyrus/ext.rb +1 -1
  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 +22 -20
  33. data/lib/tapyrus/message/addr.rb +1 -7
  34. data/lib/tapyrus/message/base.rb +0 -3
  35. data/lib/tapyrus/message/block.rb +2 -9
  36. data/lib/tapyrus/message/block_transaction_request.rb +3 -6
  37. data/lib/tapyrus/message/block_transactions.rb +2 -6
  38. data/lib/tapyrus/message/block_txn.rb +0 -4
  39. data/lib/tapyrus/message/cmpct_block.rb +1 -7
  40. data/lib/tapyrus/message/error.rb +1 -4
  41. data/lib/tapyrus/message/fee_filter.rb +1 -4
  42. data/lib/tapyrus/message/filter_add.rb +0 -4
  43. data/lib/tapyrus/message/filter_clear.rb +0 -4
  44. data/lib/tapyrus/message/filter_load.rb +2 -5
  45. data/lib/tapyrus/message/get_addr.rb +0 -4
  46. data/lib/tapyrus/message/get_block_txn.rb +0 -4
  47. data/lib/tapyrus/message/get_blocks.rb +0 -3
  48. data/lib/tapyrus/message/get_data.rb +1 -4
  49. data/lib/tapyrus/message/get_headers.rb +1 -3
  50. data/lib/tapyrus/message/header_and_short_ids.rb +3 -9
  51. data/lib/tapyrus/message/headers.rb +0 -4
  52. data/lib/tapyrus/message/headers_parser.rb +3 -8
  53. data/lib/tapyrus/message/inv.rb +1 -4
  54. data/lib/tapyrus/message/inventories_parser.rb +2 -7
  55. data/lib/tapyrus/message/inventory.rb +12 -5
  56. data/lib/tapyrus/message/mem_pool.rb +0 -4
  57. data/lib/tapyrus/message/merkle_block.rb +4 -9
  58. data/lib/tapyrus/message/network_addr.rb +7 -6
  59. data/lib/tapyrus/message/not_found.rb +0 -3
  60. data/lib/tapyrus/message/ping.rb +0 -3
  61. data/lib/tapyrus/message/pong.rb +0 -3
  62. data/lib/tapyrus/message/prefilled_tx.rb +0 -4
  63. data/lib/tapyrus/message/reject.rb +0 -3
  64. data/lib/tapyrus/message/send_cmpct.rb +1 -3
  65. data/lib/tapyrus/message/send_headers.rb +0 -3
  66. data/lib/tapyrus/message/tx.rb +0 -4
  67. data/lib/tapyrus/message/ver_ack.rb +1 -5
  68. data/lib/tapyrus/message/version.rb +2 -5
  69. data/lib/tapyrus/message.rb +14 -16
  70. data/lib/tapyrus/mnemonic.rb +17 -15
  71. data/lib/tapyrus/network/connection.rb +0 -3
  72. data/lib/tapyrus/network/message_handler.rb +61 -60
  73. data/lib/tapyrus/network/peer.rb +13 -12
  74. data/lib/tapyrus/network/peer_discovery.rb +10 -9
  75. data/lib/tapyrus/network/pool.rb +12 -12
  76. data/lib/tapyrus/network.rb +0 -2
  77. data/lib/tapyrus/node/cli.rb +12 -14
  78. data/lib/tapyrus/node/configuration.rb +1 -3
  79. data/lib/tapyrus/node/spv.rb +2 -3
  80. data/lib/tapyrus/node.rb +1 -1
  81. data/lib/tapyrus/opcodes.rb +9 -7
  82. data/lib/tapyrus/out_point.rb +5 -5
  83. data/lib/tapyrus/rpc/http_server.rb +21 -22
  84. data/lib/tapyrus/rpc/request_handler.rb +42 -44
  85. data/lib/tapyrus/rpc/tapyrus_core_client.rb +67 -25
  86. data/lib/tapyrus/rpc.rb +1 -0
  87. data/lib/tapyrus/script/color.rb +10 -0
  88. data/lib/tapyrus/script/multisig.rb +13 -12
  89. data/lib/tapyrus/script/script.rb +99 -88
  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/native.rb +14 -15
  94. data/lib/tapyrus/secp256k1/rfc6979.rb +7 -4
  95. data/lib/tapyrus/secp256k1/ruby.rb +10 -12
  96. data/lib/tapyrus/secp256k1.rb +0 -4
  97. data/lib/tapyrus/slip39/share.rb +41 -29
  98. data/lib/tapyrus/slip39/sss.rb +107 -57
  99. data/lib/tapyrus/slip39.rb +20 -5
  100. data/lib/tapyrus/store/chain_entry.rb +0 -4
  101. data/lib/tapyrus/store/db/level_db.rb +5 -9
  102. data/lib/tapyrus/store/db.rb +0 -2
  103. data/lib/tapyrus/store/spv_chain.rb +11 -17
  104. data/lib/tapyrus/store.rb +1 -3
  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/lib/tapyrus.rb +8 -30
  117. data/tapyrusrb.gemspec +13 -14
  118. metadata +26 -7
  119. data/.travis.yml +0 -14
@@ -0,0 +1,158 @@
1
+ module Tapyrus
2
+ #
3
+ # Transaction Builder class.
4
+ #
5
+ # TxBuilder makes it easy to build transactions without having to deal with TxOut/TxIn/Script directly.
6
+ #
7
+ # @example
8
+ #
9
+ # txb = Tapyrus::TxBuilder.new
10
+ # utxo1 = {
11
+ # script_pubkey: Tapyrus::Script.parse_from_addr('mgCuyNQ1pUbKqL57tJQZX3hhUCaZcuX3RQ'),
12
+ # txid: 'e1fb3255ead43dccd3ae0ac2c4f81b32260ca52749936a739669918bbb895411',
13
+ # index: 0,
14
+ # value: 3_000
15
+ # }
16
+ # color_id = Tapyrus::Color::ColorIdentifier.nft(...)
17
+ # utxo2 = {
18
+ # script_pubkey: Tapyrus::Script.parse_from_addr('mu9QMUcB9UCHbQjZJLAuyysQhM9tmFQbPx'),
19
+ # color_id: color_id,
20
+ # txid: 'e1fb3255ead43dccd3ae0ac2c4f81b32260ca52749936a739669918bbb895411',
21
+ # index: 1,
22
+ # value: 3_000
23
+ # }
24
+ #
25
+ # tx = txb
26
+ # .add_utxo(utxo1)
27
+ # .add_utxo(utxo2)
28
+ # .data("0102030405060a0b0c")
29
+ # .reissuable(utxo1[:script_pubkey],'n4jKJN5UMLsAejL1M5CTzQ8npeWoLBLCAH', 10_000)
30
+ # .pay('n4jKJN5UMLsAejL1M5CTzQ8npeWoLBLCAH', 1_000)
31
+ # .build
32
+ #
33
+ class TxBuilder
34
+ def initialize
35
+ @utxos = []
36
+ @incomings = {}
37
+ @outgoings = {}
38
+ @outputs = []
39
+ end
40
+
41
+ # Add utxo for transaction input
42
+ # @param utxo [Hash] a hash whose fields are `txid`, `index`, `script_pubkey`, `value`, and `color_id` (color_id is optional)
43
+ def add_utxo(utxo)
44
+ @utxos << utxo
45
+ color_id = utxo[:color_id] || Tapyrus::Color::ColorIdentifier.default
46
+ @incomings[color_id] ||= 0
47
+ @incomings[color_id] += utxo[:value]
48
+ self
49
+ end
50
+
51
+ # Issue reissuable token
52
+ # @param script_pubkey [Tapyrus::Script] the script pubkey in the issue input.
53
+ # @param address [String] p2pkh or p2sh address.
54
+ # @param value [Integer] issued amount.
55
+ def reissuable(script_pubkey, address, value)
56
+ color_id = Tapyrus::Color::ColorIdentifier.reissuable(script_pubkey)
57
+ pay(address, value, color_id)
58
+ end
59
+
60
+ # Issue non reissuable token
61
+ # @param out_point [Tapyrus::OutPoint] the out point at issue input.
62
+ # @param address [String] p2pkh or p2sh address.
63
+ # @param value [Integer] issued amount.
64
+ def non_reissuable(out_point, address, value)
65
+ color_id = Tapyrus::Color::ColorIdentifier.non_reissuable(out_point)
66
+ pay(address, value, color_id)
67
+ end
68
+
69
+ # Issue NFT
70
+ # @param out_point [Tapyrus::OutPoint] the out point at issue input.
71
+ # @param address [String] p2pkh or p2sh address.
72
+ # @param value [Integer] issued amount.
73
+ def nft(out_point, address)
74
+ color_id = Tapyrus::Color::ColorIdentifier.nft(out_point)
75
+ pay(address, 1, color_id)
76
+ end
77
+
78
+ # Create payment output.
79
+ # @param address [String] tapyrus address with Base58 format
80
+ # @param value [Integer] issued or transferred amount
81
+ # @param color_id [Tapyrus::Color::ColorIdentifier] color id
82
+ def pay(address, value, color_id = Tapyrus::Color::ColorIdentifier.default)
83
+ script_pubkey = Tapyrus::Script.parse_from_addr(address)
84
+
85
+ unless color_id.default?
86
+ raise ArgumentError, 'invalid address' if !script_pubkey.p2pkh? && !script_pubkey.p2sh?
87
+ script_pubkey = script_pubkey.add_color(color_id)
88
+ end
89
+
90
+ @outgoings[color_id] ||= 0
91
+ @outgoings[color_id] += value
92
+ @outputs << Tapyrus::TxOut.new(script_pubkey: script_pubkey, value: value)
93
+ self
94
+ end
95
+
96
+ # Create data output
97
+ # @param contents [[String]] array of hex string
98
+ def data(*contents)
99
+ payload = contents.join
100
+ script = Tapyrus::Script.new << Tapyrus::Script::OP_RETURN << payload
101
+ @outputs << Tapyrus::TxOut.new(script_pubkey: script)
102
+ self
103
+ end
104
+
105
+ # Set transaction fee.
106
+ # @param fee [Integer] transaction fee
107
+ def fee(fee)
108
+ @fee = fee
109
+ self
110
+ end
111
+
112
+ # Set address for change.
113
+ # If set, #build method add output for change which has the specified address
114
+ # If not set, transaction built by #build method has no output for change.
115
+ # @param address [String] p2pkh or p2sh address.
116
+ def change_address(address)
117
+ script_pubkey = Tapyrus::Script.parse_from_addr(address)
118
+ raise ArgumentError, 'invalid address' if !script_pubkey.p2pkh? && !script_pubkey.p2sh?
119
+ @change_script_pubkey = script_pubkey
120
+ self
121
+ end
122
+
123
+ # Build transaction
124
+ def build
125
+ tx = Tapyrus::Tx.new
126
+ expand_input(tx)
127
+ @outputs.each { |output| tx.outputs << output }
128
+ add_change(tx) if @change_script_pubkey
129
+ tx
130
+ end
131
+
132
+ private
133
+
134
+ def add_change(tx)
135
+ @incomings.each do |color_id, in_amount|
136
+ out_amount = @outgoings[color_id] || 0
137
+ change, script_pubkey =
138
+ if color_id.default?
139
+ [in_amount - out_amount - estimated_fee, @change_script_pubkey]
140
+ else
141
+ [in_amount - out_amount, @change_script_pubkey.add_color(color_id)]
142
+ end
143
+ tx.outputs << Tapyrus::TxOut.new(script_pubkey: script_pubkey, value: change) if change > 0
144
+ end
145
+ end
146
+
147
+ def expand_input(tx)
148
+ @utxos.each do |utxo|
149
+ tx.inputs << Tapyrus::TxIn.new(out_point: Tapyrus::OutPoint.from_txid(utxo[:txid], utxo[:index]))
150
+ end
151
+ end
152
+
153
+ # Return transaction fee
154
+ def estimated_fee
155
+ @fee
156
+ end
157
+ end
158
+ end
data/lib/tapyrus/tx_in.rb CHANGED
@@ -2,10 +2,8 @@
2
2
  # https://github.com/lian/bitcoin-ruby/blob/master/COPYING
3
3
 
4
4
  module Tapyrus
5
-
6
5
  # transaction input
7
6
  class TxIn
8
-
9
7
  attr_accessor :out_point
10
8
  attr_accessor :script_sig
11
9
  attr_accessor :sequence
@@ -58,11 +56,10 @@ module Tapyrus
58
56
  p
59
57
  end
60
58
 
61
-
62
59
  def to_h
63
60
  sig = script_sig.to_h
64
61
  sig.delete(:type)
65
- h = {txid: out_point.txid, vout: out_point.index, script_sig: sig }
62
+ h = { txid: out_point.txid, vout: out_point.index, script_sig: sig }
66
63
  h[:sequence] = sequence
67
64
  h
68
65
  end
@@ -76,7 +73,5 @@ module Tapyrus
76
73
  return nil unless out_point
77
74
  out_point.tx_hash
78
75
  end
79
-
80
76
  end
81
-
82
77
  end
@@ -2,10 +2,8 @@
2
2
  # https://github.com/lian/bitcoin-ruby/blob/master/COPYING
3
3
 
4
4
  module Tapyrus
5
-
6
5
  # transaction output
7
6
  class TxOut
8
-
9
7
  include OpenAssets::MarkerOutput
10
8
  include Tapyrus::Color::ColoredOutput
11
9
 
@@ -39,7 +37,7 @@ module Tapyrus
39
37
  end
40
38
 
41
39
  def to_h
42
- {value: value_to_btc, script_pubkey: script_pubkey.to_h}
40
+ { value: value_to_btc, script_pubkey: script_pubkey.to_h }
43
41
  end
44
42
 
45
43
  def ==(other)
@@ -65,11 +63,8 @@ module Tapyrus
65
63
  n_size = size
66
64
  n_size += (32 + 4 + 1 + 107 + 4)
67
65
  fee = n_size * Tapyrus.chain_params.dust_relay_fee / 1000
68
- if fee == 0 && n_size != 0
69
- fee = Tapyrus.chain_params.dust_relay_fee > 0 ? 1 : -1
70
- end
66
+ fee = Tapyrus.chain_params.dust_relay_fee > 0 ? 1 : -1 if fee == 0 && n_size != 0
71
67
  fee
72
68
  end
73
69
  end
74
-
75
70
  end
data/lib/tapyrus/util.rb CHANGED
@@ -2,12 +2,10 @@
2
2
  # https://github.com/lian/bitcoin-ruby/blob/master/COPYING
3
3
 
4
4
  module Tapyrus
5
-
6
5
  # tapyrus utility.
7
6
  # following methods can be used as follows.
8
7
  # Tapyrus.pack_var_int(5)
9
8
  module Util
10
-
11
9
  def pack_var_string(payload)
12
10
  pack_var_int(payload.bytesize) + payload
13
11
  end
@@ -18,7 +16,7 @@ module Tapyrus
18
16
  end
19
17
 
20
18
  def pack_var_int(i)
21
- if i < 0xfd
19
+ if i < 0xfd
22
20
  [i].pack('C')
23
21
  elsif i <= 0xffff
24
22
  [0xfd, i].pack('Cv')
@@ -111,7 +109,14 @@ module Tapyrus
111
109
  def decode_base58_address(addr)
112
110
  hex = Base58.decode(addr)
113
111
  if hex.size == 50 && calc_checksum(hex[0...-8]) == hex[-8..-1]
114
- raise 'Invalid version bytes.' unless [Tapyrus.chain_params.address_version, Tapyrus.chain_params.p2sh_version].include?(hex[0..1])
112
+ unless [Tapyrus.chain_params.address_version, Tapyrus.chain_params.p2sh_version].include?(hex[0..1])
113
+ raise 'Invalid version bytes.'
114
+ end
115
+ [hex[2...-8], hex[0..1]]
116
+ elsif hex.size == 116 && calc_checksum(hex[0...-8]) == hex[-8..-1]
117
+ unless [Tapyrus.chain_params.cp2pkh_version, Tapyrus.chain_params.cp2sh_version].include?(hex[0..1])
118
+ raise 'Invalid version bytes.'
119
+ end
115
120
  [hex[2...-8], hex[0..1]]
116
121
  else
117
122
  raise 'Invalid address.'
@@ -128,14 +133,22 @@ module Tapyrus
128
133
  OpenSSL::HMAC.digest(DIGEST_NAME_SHA256, key, data)
129
134
  end
130
135
 
136
+ # check whether +addr+ is valid address.
137
+ # @param [String] addr an address
138
+ # @return [Boolean] if valid address return true, otherwise false.
139
+ def valid_address?(addr)
140
+ begin
141
+ Tapyrus::Script.parse_from_addr(addr)
142
+ true
143
+ rescue Exception => e
144
+ false
145
+ end
146
+ end
131
147
  end
132
148
 
133
149
  module HexConverter
134
-
135
150
  def to_hex
136
151
  to_payload.bth
137
152
  end
138
-
139
153
  end
140
-
141
154
  end
@@ -1,7 +1,5 @@
1
1
  module Tapyrus
2
-
3
2
  class Validation
4
-
5
3
  # check transaction validation
6
4
  def check_tx(tx, state)
7
5
  # Basic checks that don't depend on any context
@@ -16,14 +14,20 @@ module Tapyrus
16
14
  # Check for negative or overflow output values
17
15
  amount = 0
18
16
  tx.outputs.each do |o|
19
- return state.DoS(100, reject_code: Message::Reject::CODE_INVALID, reject_reason: 'bad-txns-vout-negative') if o.value < 0
20
- return state.DoS(100, reject_code: Message::Reject::CODE_INVALID, reject_reason: 'bad-txns-vout-toolarge') if MAX_MONEY < o.value
17
+ if o.value < 0
18
+ return state.DoS(100, reject_code: Message::Reject::CODE_INVALID, reject_reason: 'bad-txns-vout-negative')
19
+ end
20
+ if MAX_MONEY < o.value
21
+ return state.DoS(100, reject_code: Message::Reject::CODE_INVALID, reject_reason: 'bad-txns-vout-toolarge')
22
+ end
21
23
  amount += o.value
22
- return state.DoS(100, reject_code: Message::Reject::CODE_INVALID, reject_reason: 'bad-txns-vout-toolarge') if MAX_MONEY < amount
24
+ if MAX_MONEY < amount
25
+ return state.DoS(100, reject_code: Message::Reject::CODE_INVALID, reject_reason: 'bad-txns-vout-toolarge')
26
+ end
23
27
  end
24
28
 
25
29
  # Check for duplicate inputs - note that this check is slow so we skip it in CheckBlock
26
- out_points = tx.inputs.map{|i|i.out_point.to_payload}
30
+ out_points = tx.inputs.map { |i| i.out_point.to_payload }
27
31
  unless out_points.size == out_points.uniq.size
28
32
  return state.DoS(100, reject_code: Message::Reject::CODE_INVALID, reject_reason: 'bad-txns-inputs-duplicate')
29
33
  end
@@ -46,7 +50,6 @@ module Tapyrus
46
50
  def check_block_header(header, state)
47
51
  header.block_hash
48
52
  header.bits
49
-
50
53
  end
51
54
 
52
55
  def check_block(block, state)
@@ -63,12 +66,10 @@ module Tapyrus
63
66
 
64
67
  # check sigop count
65
68
  end
66
-
67
69
  end
68
70
 
69
71
  class ValidationState
70
-
71
- MODE = {valid: 0, invlid: 1, error: 2}
72
+ MODE = { valid: 0, invlid: 1, error: 2 }
72
73
 
73
74
  attr_accessor :mode
74
75
  attr_accessor :n_dos
@@ -107,4 +108,4 @@ module Tapyrus
107
108
  mode == MODE[:error]
108
109
  end
109
110
  end
110
- end
111
+ end
@@ -1,3 +1,3 @@
1
1
  module Tapyrus
2
- VERSION = "0.2.6"
2
+ VERSION = '0.2.10'
3
3
  end
@@ -1,11 +1,10 @@
1
1
  module Tapyrus
2
2
  module Wallet
3
-
4
3
  # the account in BIP-44
5
4
  class Account
6
5
  include Tapyrus::HexConverter
7
6
 
8
- PURPOSE_TYPE = {legacy: 44, nested_witness: 49, native_segwit: 84}
7
+ PURPOSE_TYPE = { legacy: 44, nested_witness: 49, native_segwit: 84 }
9
8
 
10
9
  attr_reader :purpose # either 44 or 49 or 84
11
10
  attr_reader :index # BIP-44 index
@@ -86,26 +85,26 @@ module Tapyrus
86
85
  # get the list of derived keys for receive key.
87
86
  # @return [Array[Tapyrus::ExtPubkey]]
88
87
  def derived_receive_keys
89
- (receive_depth + 1).times.map{|i|derive_key(0,i)}
88
+ (receive_depth + 1).times.map { |i| derive_key(0, i) }
90
89
  end
91
90
 
92
91
  # get the list of derived keys for change key.
93
92
  # @return [Array[Tapyrus::ExtPubkey]]
94
93
  def derived_change_keys
95
- (change_depth + 1).times.map{|i|derive_key(1,i)}
94
+ (change_depth + 1).times.map { |i| derive_key(1, i) }
96
95
  end
97
96
 
98
97
  # get account type label.
99
98
  def type
100
99
  case purpose
101
- when PURPOSE_TYPE[:legacy]
102
- 'pubkeyhash'
103
- when PURPOSE_TYPE[:nested_witness]
104
- 'p2wpkh-p2sh'
105
- when PURPOSE_TYPE[:native_segwit]
106
- 'p2wpkh'
107
- else
108
- 'unknown'
100
+ when PURPOSE_TYPE[:legacy]
101
+ 'pubkeyhash'
102
+ when PURPOSE_TYPE[:nested_witness]
103
+ 'p2wpkh-p2sh'
104
+ when PURPOSE_TYPE[:native_segwit]
105
+ 'p2wpkh'
106
+ else
107
+ 'unknown'
109
108
  end
110
109
  end
111
110
 
@@ -126,10 +125,17 @@ module Tapyrus
126
125
 
127
126
  def to_h
128
127
  {
129
- name: name, type: type, index: index, receive_depth: receive_depth, change_depth: change_depth,
130
- look_ahead: lookahead, receive_address: derive_key(0, receive_depth).addr,
131
- change_address: derive_key(1, change_depth).addr,
132
- account_key: account_key.to_base58, path: path, watch_only: watch_only
128
+ name: name,
129
+ type: type,
130
+ index: index,
131
+ receive_depth: receive_depth,
132
+ change_depth: change_depth,
133
+ look_ahead: lookahead,
134
+ receive_address: derive_key(0, receive_depth).addr,
135
+ change_address: derive_key(1, change_depth).addr,
136
+ account_key: account_key.to_base58,
137
+ path: path,
138
+ watch_only: watch_only
133
139
  }
134
140
  end
135
141
 
@@ -145,8 +151,6 @@ module Tapyrus
145
151
  version_bytes = Tapyrus::ExtPubkey.version_from_purpose(purpose + Tapyrus::HARDENED_THRESHOLD)
146
152
  raise 'The purpose and the account key do not match.' unless account_key.version == version_bytes
147
153
  end
148
-
149
154
  end
150
-
151
155
  end
152
156
  end
@@ -2,9 +2,7 @@ require 'leveldb-native'
2
2
 
3
3
  module Tapyrus
4
4
  module Wallet
5
-
6
5
  class Base
7
-
8
6
  attr_accessor :wallet_id
9
7
  attr_reader :db
10
8
  attr_reader :path
@@ -24,6 +22,7 @@ module Tapyrus
24
22
  def self.create(wallet_id = 1, path_prefix = default_path_prefix)
25
23
  raise ArgumentError, "wallet_id : #{wallet_id} already exist." if self.exist?(wallet_id, path_prefix)
26
24
  w = self.new(wallet_id, path_prefix)
25
+
27
26
  # generate seed
28
27
  raise RuntimeError, 'the seed already exist.' if w.db.registered_master?
29
28
  master = Tapyrus::Wallet::MasterKey.generate
@@ -122,14 +121,20 @@ module Tapyrus
122
121
 
123
122
  # decrypt wallet
124
123
  # @param [String] passphrase the wallet passphrase
125
- def decrypt(passphrase)
126
-
127
- end
124
+ def decrypt(passphrase); end
128
125
 
129
126
  # wallet information
130
127
  def to_h
131
128
  a = accounts.map(&:to_h)
132
- { wallet_id: wallet_id, version: version, account_depth: a.size, accounts: a, master: {encrypted: master_key.encrypted} }
129
+ {
130
+ wallet_id: wallet_id,
131
+ version: version,
132
+ account_depth: a.size,
133
+ accounts: a,
134
+ master: {
135
+ encrypted: master_key.encrypted
136
+ }
137
+ }
133
138
  end
134
139
 
135
140
  # get data elements tobe monitored with Bloom Filter.
@@ -153,10 +158,8 @@ module Tapyrus
153
158
 
154
159
  # find account using +account_name+
155
160
  def find_account(account_name, purpose = nil)
156
- accounts(purpose).find{|a| a.name == account_name}
161
+ accounts(purpose).find { |a| a.name == account_name }
157
162
  end
158
-
159
163
  end
160
-
161
164
  end
162
165
  end
@@ -1,13 +1,11 @@
1
1
  module Tapyrus
2
2
  module Wallet
3
-
4
3
  class DB
5
-
6
4
  KEY_PREFIX = {
7
- account: 'a', # key: account index, value: Account raw data.
8
- master: 'm', # value: wallet seed.
9
- version: 'v', # value: wallet version
10
- key: 'k', # key: path to the key, value: public key
5
+ account: 'a', # key: account index, value: Account raw data.
6
+ master: 'm', # value: wallet seed.
7
+ version: 'v', # value: wallet version
8
+ key: 'k' # key: path to the key, value: public key
11
9
  }
12
10
 
13
11
  attr_reader :level_db
@@ -27,7 +25,7 @@ module Tapyrus
27
25
  def accounts
28
26
  from = KEY_PREFIX[:account] + '00000000'
29
27
  to = KEY_PREFIX[:account] + 'ffffffff'
30
- level_db.each(from: from, to: to).map { |k, v| v}
28
+ level_db.each(from: from, to: to).map { |k, v| v }
31
29
  end
32
30
 
33
31
  def save_account(account)
@@ -50,7 +48,7 @@ module Tapyrus
50
48
  id = [account.purpose, account.index].pack('I*').bth
51
49
  from = KEY_PREFIX[:key] + id + '00000000'
52
50
  to = KEY_PREFIX[:key] + id + 'ffffffff'
53
- level_db.each(from: from, to: to).map { |k, v| v}
51
+ level_db.each(from: from, to: to).map { |k, v| v }
54
52
  end
55
53
 
56
54
  # get master_key
@@ -75,7 +73,6 @@ module Tapyrus
75
73
  def version
76
74
  level_db.get(KEY_PREFIX[:version]).to_i
77
75
  end
78
-
79
76
  end
80
77
  end
81
78
  end
@@ -1,6 +1,5 @@
1
1
  module Tapyrus
2
2
  module Wallet
3
-
4
3
  # HD Wallet master seed
5
4
  class MasterKey
6
5
  include Tapyrus::HexConverter
@@ -53,7 +52,7 @@ module Tapyrus
53
52
  # [encrypted(false:0, true:1)][salt(var str)][seed(var str)]
54
53
  def to_payload
55
54
  flg = encrypted ? 1 : 0
56
- pack_var_int(flg) << [salt, seed].map{|v|pack_var_string(v.htb)}.join
55
+ pack_var_int(flg) << [salt, seed].map { |v| pack_var_string(v.htb) }.join
57
56
  end
58
57
 
59
58
  # get master key
@@ -67,7 +66,7 @@ module Tapyrus
67
66
  # @return [Tapyrus::ExtKey]
68
67
  def derive(path)
69
68
  derived_key = key
70
- parse_key_path(path).each{|num| derived_key = derived_key.derive(num)}
69
+ parse_key_path(path).each { |num| derived_key = derived_key.derive(num) }
71
70
  derived_key
72
71
  end
73
72
 
@@ -105,7 +104,6 @@ module Tapyrus
105
104
  key_iv = OpenSSL::PKCS5.pbkdf2_hmac_sha1(passphrase, salt, 2000, enc.key_len + enc.iv_len)
106
105
  [key_iv[0, enc.key_len], key_iv[enc.key_len, enc.iv_len]]
107
106
  end
108
-
109
107
  end
110
108
  end
111
109
  end
data/lib/tapyrus.rb CHANGED
@@ -13,7 +13,6 @@ require_relative 'openassets'
13
13
  require_relative 'schnorr'
14
14
 
15
15
  module Tapyrus
16
-
17
16
  autoload :Ext, 'tapyrus/ext'
18
17
  autoload :Util, 'tapyrus/util'
19
18
  autoload :ChainParams, 'tapyrus/chain_params'
@@ -49,6 +48,8 @@ module Tapyrus
49
48
  autoload :SLIP39, 'tapyrus/slip39'
50
49
  autoload :Color, 'tapyrus/script/color'
51
50
  autoload :Errors, 'tapyrus/errors'
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'
@@ -59,7 +60,7 @@ module Tapyrus
59
60
 
60
61
  # set tapyrus network chain params
61
62
  def self.chain_params=(name)
62
- raise "chain params for #{name} is not defined." unless %i(prod dev).include?(name.to_sym)
63
+ raise "chain params for #{name} is not defined." unless %i[prod dev].include?(name.to_sym)
63
64
  @current_chain = nil
64
65
  @chain_param = name.to_sym
65
66
  end
@@ -118,14 +119,7 @@ module Tapyrus
118
119
 
119
120
  # get opcode
120
121
  def opcode
121
- case encoding
122
- when Encoding::ASCII_8BIT
123
- each_byte.next
124
- when Encoding::US_ASCII
125
- ord
126
- else
127
- to_i
128
- end
122
+ force_encoding(Encoding::ASCII_8BIT).ord
129
123
  end
130
124
 
131
125
  def opcode?
@@ -160,17 +154,11 @@ module Tapyrus
160
154
  def valid_hex?
161
155
  !self[/\H/]
162
156
  end
163
-
164
157
  end
165
158
 
166
159
  class ::Object
167
-
168
160
  def build_json
169
- if self.is_a?(Array)
170
- "[#{self.map{|o|o.to_h.to_json}.join(',')}]"
171
- else
172
- to_h.to_json
173
- end
161
+ self.is_a?(Array) ? "[#{self.map { |o| o.to_h.to_json }.join(',')}]" : to_h.to_json
174
162
  end
175
163
 
176
164
  def to_h
@@ -179,14 +167,9 @@ module Tapyrus
179
167
  key = var.to_s
180
168
  key.slice!(0) if key.start_with?('@')
181
169
  value = instance_variable_get(var)
182
- if value.is_a?(Array)
183
- result.update(key => value.map{|v|v.to_h})
184
- else
185
- result.update(key => value)
186
- end
170
+ value.is_a?(Array) ? result.update(key => value.map { |v| v.to_h }) : result.update(key => value)
187
171
  end
188
172
  end
189
-
190
173
  end
191
174
 
192
175
  class ::Integer
@@ -200,13 +183,8 @@ module Tapyrus
200
183
  end
201
184
 
202
185
  # convert bit string
203
- def to_bits(length = nil )
204
- if length
205
- to_s(2).rjust(length, '0')
206
- else
207
- to_s(2)
208
- end
186
+ def to_bits(length = nil)
187
+ length ? to_s(2).rjust(length, '0') : to_s(2)
209
188
  end
210
189
  end
211
-
212
190
  end