tapyrus 0.2.3 → 0.2.8

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 +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 +2 -3
  12. data/lib/schnorr/signature.rb +3 -6
  13. data/lib/tapyrus.rb +7 -30
  14. data/lib/tapyrus/base58.rb +7 -6
  15. data/lib/tapyrus/block.rb +1 -2
  16. data/lib/tapyrus/block_header.rb +15 -9
  17. data/lib/tapyrus/bloom_filter.rb +5 -3
  18. data/lib/tapyrus/chain_params.rb +1 -4
  19. data/lib/tapyrus/chainparams/dev.yml +3 -2
  20. data/lib/tapyrus/chainparams/prod.yml +3 -2
  21. data/lib/tapyrus/constants.rb +29 -23
  22. data/lib/tapyrus/errors.rb +1 -3
  23. data/lib/tapyrus/ext.rb +1 -1
  24. data/lib/tapyrus/ext/ecdsa.rb +4 -4
  25. data/lib/tapyrus/ext/json_parser.rb +1 -4
  26. data/lib/tapyrus/ext_key.rb +38 -34
  27. data/lib/tapyrus/key.rb +31 -35
  28. data/lib/tapyrus/key_path.rb +15 -12
  29. data/lib/tapyrus/logger.rb +20 -16
  30. data/lib/tapyrus/merkle_tree.rb +19 -20
  31. data/lib/tapyrus/message.rb +14 -16
  32. data/lib/tapyrus/message/addr.rb +1 -7
  33. data/lib/tapyrus/message/base.rb +0 -3
  34. data/lib/tapyrus/message/block.rb +2 -9
  35. data/lib/tapyrus/message/block_transaction_request.rb +3 -6
  36. data/lib/tapyrus/message/block_transactions.rb +2 -6
  37. data/lib/tapyrus/message/block_txn.rb +0 -4
  38. data/lib/tapyrus/message/cmpct_block.rb +1 -7
  39. data/lib/tapyrus/message/error.rb +1 -4
  40. data/lib/tapyrus/message/fee_filter.rb +1 -4
  41. data/lib/tapyrus/message/filter_add.rb +0 -4
  42. data/lib/tapyrus/message/filter_clear.rb +0 -4
  43. data/lib/tapyrus/message/filter_load.rb +2 -5
  44. data/lib/tapyrus/message/get_addr.rb +0 -4
  45. data/lib/tapyrus/message/get_block_txn.rb +0 -4
  46. data/lib/tapyrus/message/get_blocks.rb +0 -3
  47. data/lib/tapyrus/message/get_data.rb +1 -4
  48. data/lib/tapyrus/message/get_headers.rb +1 -3
  49. data/lib/tapyrus/message/header_and_short_ids.rb +3 -9
  50. data/lib/tapyrus/message/headers.rb +0 -4
  51. data/lib/tapyrus/message/headers_parser.rb +3 -8
  52. data/lib/tapyrus/message/inv.rb +1 -4
  53. data/lib/tapyrus/message/inventories_parser.rb +2 -7
  54. data/lib/tapyrus/message/inventory.rb +12 -5
  55. data/lib/tapyrus/message/mem_pool.rb +0 -4
  56. data/lib/tapyrus/message/merkle_block.rb +4 -9
  57. data/lib/tapyrus/message/network_addr.rb +7 -6
  58. data/lib/tapyrus/message/not_found.rb +0 -3
  59. data/lib/tapyrus/message/ping.rb +0 -3
  60. data/lib/tapyrus/message/pong.rb +0 -3
  61. data/lib/tapyrus/message/prefilled_tx.rb +0 -4
  62. data/lib/tapyrus/message/reject.rb +0 -3
  63. data/lib/tapyrus/message/send_cmpct.rb +1 -3
  64. data/lib/tapyrus/message/send_headers.rb +0 -3
  65. data/lib/tapyrus/message/tx.rb +0 -4
  66. data/lib/tapyrus/message/ver_ack.rb +1 -5
  67. data/lib/tapyrus/message/version.rb +2 -5
  68. data/lib/tapyrus/mnemonic.rb +17 -15
  69. data/lib/tapyrus/network.rb +0 -2
  70. data/lib/tapyrus/network/connection.rb +0 -3
  71. data/lib/tapyrus/network/message_handler.rb +61 -60
  72. data/lib/tapyrus/network/peer.rb +13 -12
  73. data/lib/tapyrus/network/peer_discovery.rb +3 -5
  74. data/lib/tapyrus/network/pool.rb +12 -12
  75. data/lib/tapyrus/node.rb +1 -1
  76. data/lib/tapyrus/node/cli.rb +12 -14
  77. data/lib/tapyrus/node/configuration.rb +1 -3
  78. data/lib/tapyrus/node/spv.rb +2 -3
  79. data/lib/tapyrus/opcodes.rb +9 -7
  80. data/lib/tapyrus/out_point.rb +5 -5
  81. data/lib/tapyrus/rpc/http_server.rb +21 -22
  82. data/lib/tapyrus/rpc/request_handler.rb +42 -44
  83. data/lib/tapyrus/rpc/tapyrus_core_client.rb +53 -25
  84. data/lib/tapyrus/script/color.rb +20 -2
  85. data/lib/tapyrus/script/multisig.rb +13 -12
  86. data/lib/tapyrus/script/script.rb +104 -67
  87. data/lib/tapyrus/script/script_error.rb +1 -4
  88. data/lib/tapyrus/script/script_interpreter.rb +439 -399
  89. data/lib/tapyrus/script/tx_checker.rb +20 -10
  90. data/lib/tapyrus/secp256k1.rb +0 -4
  91. data/lib/tapyrus/secp256k1/native.rb +17 -18
  92. data/lib/tapyrus/secp256k1/rfc6979.rb +7 -4
  93. data/lib/tapyrus/secp256k1/ruby.rb +10 -12
  94. data/lib/tapyrus/slip39.rb +20 -5
  95. data/lib/tapyrus/slip39/share.rb +41 -29
  96. data/lib/tapyrus/slip39/sss.rb +101 -57
  97. data/lib/tapyrus/store.rb +1 -3
  98. data/lib/tapyrus/store/chain_entry.rb +0 -4
  99. data/lib/tapyrus/store/db.rb +0 -2
  100. data/lib/tapyrus/store/db/level_db.rb +5 -9
  101. data/lib/tapyrus/store/spv_chain.rb +11 -17
  102. data/lib/tapyrus/tx.rb +45 -37
  103. data/lib/tapyrus/tx_builder.rb +158 -0
  104. data/lib/tapyrus/tx_in.rb +1 -6
  105. data/lib/tapyrus/tx_out.rb +2 -7
  106. data/lib/tapyrus/util.rb +20 -7
  107. data/lib/tapyrus/validation.rb +12 -11
  108. data/lib/tapyrus/version.rb +1 -1
  109. data/lib/tapyrus/wallet/account.rb +22 -18
  110. data/lib/tapyrus/wallet/base.rb +12 -9
  111. data/lib/tapyrus/wallet/db.rb +6 -9
  112. data/lib/tapyrus/wallet/master_key.rb +2 -4
  113. data/tapyrusrb.gemspec +13 -16
  114. metadata +20 -31
  115. data/.travis.yml +0 -12
@@ -1,8 +1,6 @@
1
1
  module Tapyrus
2
-
3
2
  # tapyrus script error
4
3
  class ScriptError < Exception
5
-
6
4
  attr_accessor :code
7
5
  attr_accessor :extra_msg
8
6
 
@@ -100,6 +98,5 @@ module Tapyrus
100
98
  def self.name_to_code(name)
101
99
  NAME_MAP[name]
102
100
  end
103
-
104
101
  end
105
- end
102
+ end
@@ -1,7 +1,5 @@
1
1
  module Tapyrus
2
-
3
2
  class ScriptInterpreter
4
-
5
3
  include Tapyrus::Opcodes
6
4
 
7
5
  attr_reader :stack
@@ -11,8 +9,23 @@ module Tapyrus
11
9
  attr_reader :checker
12
10
  attr_reader :require_minimal
13
11
 
14
- DISABLE_OPCODES = [OP_CAT, OP_SUBSTR, OP_LEFT, OP_RIGHT, OP_INVERT, OP_AND, OP_OR, OP_XOR, OP_2MUL, OP_2DIV, OP_DIV, OP_MUL, OP_MOD, OP_LSHIFT, OP_RSHIFT]
15
-
12
+ DISABLE_OPCODES = [
13
+ OP_CAT,
14
+ OP_SUBSTR,
15
+ OP_LEFT,
16
+ OP_RIGHT,
17
+ OP_INVERT,
18
+ OP_AND,
19
+ OP_OR,
20
+ OP_XOR,
21
+ OP_2MUL,
22
+ OP_2DIV,
23
+ OP_DIV,
24
+ OP_MUL,
25
+ OP_MOD,
26
+ OP_LSHIFT,
27
+ OP_RSHIFT
28
+ ]
16
29
 
17
30
  # syntax sugar for simple evaluation for script.
18
31
  # @param [Tapyrus::Script] script_sig a scriptSig.
@@ -34,7 +47,6 @@ module Tapyrus
34
47
  # @param [Tapyrus::Script] script_pubkey a script pubkey (locking script)
35
48
  # @return [Boolean] result
36
49
  def verify_script(script_sig, script_pubkey)
37
-
38
50
  return set_error(SCRIPT_ERR_SIG_PUSHONLY) if flag?(SCRIPT_VERIFY_SIGPUSHONLY) && !script_sig.push_only?
39
51
 
40
52
  stack_copy = nil
@@ -97,9 +109,7 @@ module Tapyrus
97
109
  opcode = c.opcode
98
110
 
99
111
  if need_exec && c.pushdata?
100
- if require_minimal && !minimal_push?(c.pushed_data, opcode)
101
- return set_error(SCRIPT_ERR_MINIMALDATA)
102
- end
112
+ return set_error(SCRIPT_ERR_MINIMALDATA) if require_minimal && !minimal_push?(c.pushed_data, opcode)
103
113
  return set_error(SCRIPT_ERR_BAD_OPCODE) unless verify_pushdata_length(c)
104
114
  stack << c.pushed_data.bth
105
115
  else
@@ -107,385 +117,415 @@ module Tapyrus
107
117
  return set_error(SCRIPT_ERR_OP_COUNT)
108
118
  end
109
119
  return set_error(SCRIPT_ERR_DISABLED_OPCODE) if DISABLE_OPCODES.include?(opcode)
110
- return set_error(SCRIPT_ERR_OP_CODESEPARATOR) if opcode == OP_CODESEPARATOR && sig_version == :base && flag?(SCRIPT_VERIFY_CONST_SCRIPTCODE)
120
+ if opcode == OP_CODESEPARATOR && sig_version == :base && flag?(SCRIPT_VERIFY_CONST_SCRIPTCODE)
121
+ return set_error(SCRIPT_ERR_OP_CODESEPARATOR)
122
+ end
111
123
  next unless (need_exec || (OP_IF <= opcode && opcode <= OP_ENDIF))
112
124
  small_int = Opcodes.opcode_to_small_int(opcode)
113
125
  if small_int && opcode != OP_0
114
126
  push_int(small_int)
115
127
  else
116
128
  case opcode
117
- when OP_0
118
- stack << ''
119
- when OP_DEPTH
120
- push_int(stack.size)
121
- when OP_EQUAL, OP_EQUALVERIFY
122
- return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 2
123
- a, b = pop_string(2)
124
- result = a == b
125
- push_int(result ? 1 : 0)
126
- if opcode == OP_EQUALVERIFY
127
- if result
128
- stack.pop
129
- else
130
- return set_error(SCRIPT_ERR_EQUALVERIFY)
131
- end
129
+ when OP_0
130
+ stack << ''
131
+ when OP_DEPTH
132
+ push_int(stack.size)
133
+ when OP_EQUAL, OP_EQUALVERIFY
134
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 2
135
+ a, b = pop_string(2)
136
+ result = a == b
137
+ push_int(result ? 1 : 0)
138
+ if opcode == OP_EQUALVERIFY
139
+ if result
140
+ stack.pop
141
+ else
142
+ return set_error(SCRIPT_ERR_EQUALVERIFY)
132
143
  end
133
- when OP_0NOTEQUAL
134
- return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 1
135
- push_int(pop_int == 0 ? 0 : 1)
136
- when OP_ADD
137
- return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 2
138
- a, b = pop_int(2)
139
- push_int(a + b)
140
- when OP_1ADD
141
- return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 1
142
- push_int(pop_int + 1)
143
- when OP_SUB
144
- return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 2
145
- a, b = pop_int(2)
146
- push_int(a - b)
147
- when OP_1SUB
148
- return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 1
149
- push_int(pop_int - 1)
150
- when OP_IF, OP_NOTIF
151
- result = false
152
- if need_exec
153
- return set_error(SCRIPT_ERR_UNBALANCED_CONDITIONAL) if stack.size < 1
154
- value = pop_string.htb
155
- if flag?(SCRIPT_VERIFY_MINIMALIF)
156
- if value.bytesize > 1 || (value.bytesize == 1 && value[0].unpack('C').first != 1)
157
- return set_error(SCRIPT_ERR_MINIMALIF)
158
- end
144
+ end
145
+ when OP_0NOTEQUAL
146
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 1
147
+ push_int(pop_int == 0 ? 0 : 1)
148
+ when OP_ADD
149
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 2
150
+ a, b = pop_int(2)
151
+ push_int(a + b)
152
+ when OP_1ADD
153
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 1
154
+ push_int(pop_int + 1)
155
+ when OP_SUB
156
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 2
157
+ a, b = pop_int(2)
158
+ push_int(a - b)
159
+ when OP_1SUB
160
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 1
161
+ push_int(pop_int - 1)
162
+ when OP_IF, OP_NOTIF
163
+ result = false
164
+ if need_exec
165
+ return set_error(SCRIPT_ERR_UNBALANCED_CONDITIONAL) if stack.size < 1
166
+ value = pop_string.htb
167
+ if flag?(SCRIPT_VERIFY_MINIMALIF)
168
+ if value.bytesize > 1 || (value.bytesize == 1 && value[0].unpack('C').first != 1)
169
+ return set_error(SCRIPT_ERR_MINIMALIF)
159
170
  end
160
- result = cast_to_bool(value)
161
- result = !result if opcode == OP_NOTIF
162
171
  end
163
- flow_stack << result
164
- when OP_ELSE
165
- return set_error(SCRIPT_ERR_UNBALANCED_CONDITIONAL) if flow_stack.size < 1
166
- flow_stack << !flow_stack.pop
167
- when OP_ENDIF
168
- return set_error(SCRIPT_ERR_UNBALANCED_CONDITIONAL) if flow_stack.empty?
169
- flow_stack.pop
170
- when OP_NOP
171
- when OP_NOP1, OP_NOP4..OP_NOP10
172
- return set_error(SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS) if flag?(SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS)
173
- when OP_CHECKLOCKTIMEVERIFY
174
- next unless flag?(SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY)
175
- return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 1
176
- # Note that elsewhere numeric opcodes are limited to operands in the range -2**31+1 to 2**31-1,
177
- # however it is legal for opcodes to produce results exceeding that range.
178
- # This limitation is implemented by CScriptNum's default 4-byte limit.
179
- # If we kept to that limit we'd have a year 2038 problem,
180
- # even though the nLockTime field in transactions themselves is uint32 which only becomes meaningless after the year 2106.
181
- # Thus as a special case we tell CScriptNum to accept up to 5-byte bignums,
182
- # which are good until 2**39-1, well beyond the 2**32-1 limit of the nLockTime field itself.
183
- locktime = cast_to_int(stack.last, 5)
184
- return set_error(SCRIPT_ERR_NEGATIVE_LOCKTIME) if locktime < 0
185
- return set_error(SCRIPT_ERR_UNSATISFIED_LOCKTIME) unless checker.check_locktime(locktime)
186
- when OP_CHECKSEQUENCEVERIFY
187
- next unless flag?(SCRIPT_VERIFY_CHECKSEQUENCEVERIFY)
188
- return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 1
189
-
190
- # nSequence, like nLockTime, is a 32-bit unsigned integer field.
191
- # See the comment in CHECKLOCKTIMEVERIFY regarding 5-byte numeric operands.
192
- sequence = cast_to_int(stack.last, 5)
193
-
194
- # In the rare event that the argument may be < 0 due to some arithmetic being done first,
195
- # you can always use 0 MAX CHECKSEQUENCEVERIFY.
196
- return set_error(SCRIPT_ERR_NEGATIVE_LOCKTIME) if sequence < 0
197
-
198
- # To provide for future soft-fork extensibility,
199
- # if the operand has the disabled lock-time flag set, CHECKSEQUENCEVERIFY behaves as a NOP.
200
- next if (sequence & Tapyrus::TxIn::SEQUENCE_LOCKTIME_DISABLE_FLAG) != 0
201
-
202
- # Compare the specified sequence number with the input.
203
- unless checker.check_sequence(sequence)
204
- return set_error(SCRIPT_ERR_UNSATISFIED_LOCKTIME)
172
+ result = cast_to_bool(value)
173
+ result = !result if opcode == OP_NOTIF
174
+ end
175
+ flow_stack << result
176
+ when OP_ELSE
177
+ return set_error(SCRIPT_ERR_UNBALANCED_CONDITIONAL) if flow_stack.size < 1
178
+ flow_stack << !flow_stack.pop
179
+ when OP_ENDIF
180
+ return set_error(SCRIPT_ERR_UNBALANCED_CONDITIONAL) if flow_stack.empty?
181
+ flow_stack.pop
182
+ when OP_NOP
183
+ when OP_NOP1, OP_NOP4..OP_NOP10
184
+ if flag?(SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS)
185
+ return set_error(SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS)
186
+ end
187
+ when OP_CHECKLOCKTIMEVERIFY
188
+ next unless flag?(SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY)
189
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 1
190
+
191
+ # Note that elsewhere numeric opcodes are limited to operands in the range -2**31+1 to 2**31-1,
192
+ # however it is legal for opcodes to produce results exceeding that range.
193
+ # This limitation is implemented by CScriptNum's default 4-byte limit.
194
+ # If we kept to that limit we'd have a year 2038 problem,
195
+ # even though the nLockTime field in transactions themselves is uint32 which only becomes meaningless after the year 2106.
196
+ # Thus as a special case we tell CScriptNum to accept up to 5-byte bignums,
197
+ # which are good until 2**39-1, well beyond the 2**32-1 limit of the nLockTime field itself.
198
+ locktime = cast_to_int(stack.last, 5)
199
+ return set_error(SCRIPT_ERR_NEGATIVE_LOCKTIME) if locktime < 0
200
+ return set_error(SCRIPT_ERR_UNSATISFIED_LOCKTIME) unless checker.check_locktime(locktime)
201
+ when OP_CHECKSEQUENCEVERIFY
202
+ next unless flag?(SCRIPT_VERIFY_CHECKSEQUENCEVERIFY)
203
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 1
204
+
205
+ # nSequence, like nLockTime, is a 32-bit unsigned integer field.
206
+ # See the comment in CHECKLOCKTIMEVERIFY regarding 5-byte numeric operands.
207
+ sequence = cast_to_int(stack.last, 5)
208
+
209
+ # In the rare event that the argument may be < 0 due to some arithmetic being done first,
210
+ # you can always use 0 MAX CHECKSEQUENCEVERIFY.
211
+ return set_error(SCRIPT_ERR_NEGATIVE_LOCKTIME) if sequence < 0
212
+
213
+ # To provide for future soft-fork extensibility,
214
+ # if the operand has the disabled lock-time flag set, CHECKSEQUENCEVERIFY behaves as a NOP.
215
+ next if (sequence & Tapyrus::TxIn::SEQUENCE_LOCKTIME_DISABLE_FLAG) != 0
216
+
217
+ # Compare the specified sequence number with the input.
218
+ return set_error(SCRIPT_ERR_UNSATISFIED_LOCKTIME) unless checker.check_sequence(sequence)
219
+ when OP_DUP
220
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 1
221
+ stack << stack.last
222
+ when OP_2DUP
223
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 2
224
+ 2.times { stack << stack[-2] }
225
+ when OP_3DUP
226
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 3
227
+ 3.times { stack << stack[-3] }
228
+ when OP_IFDUP
229
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 1
230
+ stack << stack.last if cast_to_bool(stack.last)
231
+ when OP_RIPEMD160
232
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 1
233
+ stack << Digest::RMD160.hexdigest(pop_string.htb)
234
+ when OP_SHA1
235
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 1
236
+ stack << Digest::SHA1.hexdigest(pop_string.htb)
237
+ when OP_SHA256
238
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 1
239
+ stack << Digest::SHA256.hexdigest(pop_string.htb)
240
+ when OP_HASH160
241
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 1
242
+ stack << Tapyrus.hash160(pop_string)
243
+ when OP_HASH256
244
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 1
245
+ stack << Tapyrus.double_sha256(pop_string.htb).bth
246
+ when OP_VERIFY
247
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 1
248
+ return set_error(SCRIPT_ERR_VERIFY) unless pop_bool
249
+ when OP_TOALTSTACK
250
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 1
251
+ alt_stack << stack.pop
252
+ when OP_FROMALTSTACK
253
+ return set_error(SCRIPT_ERR_INVALID_ALTSTACK_OPERATION) if alt_stack.size < 1
254
+ stack << alt_stack.pop
255
+ when OP_DROP
256
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 1
257
+ stack.pop
258
+ when OP_2DROP
259
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 2
260
+ 2.times { stack.pop }
261
+ when OP_NIP
262
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 2
263
+ stack.delete_at(-2)
264
+ when OP_OVER
265
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 2
266
+ stack << stack[-2]
267
+ when OP_2OVER
268
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 4
269
+ 2.times { stack << stack[-4] }
270
+ when OP_PICK, OP_ROLL
271
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 2
272
+ pos = pop_int
273
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if pos < 0 || pos >= stack.size
274
+ stack << stack[-pos - 1]
275
+ stack.delete_at(-pos - 2) if opcode == OP_ROLL
276
+ when OP_ROT
277
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 3
278
+ stack << stack[-3]
279
+ stack.delete_at(-4)
280
+ when OP_2ROT
281
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 6
282
+ 2.times { stack << stack[-6] }
283
+ 2.times { stack.delete_at(-7) }
284
+ when OP_SWAP
285
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 2
286
+ tmp = stack.last
287
+ stack[-1] = stack[-2]
288
+ stack[-2] = tmp
289
+ when OP_2SWAP
290
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 4
291
+ 2.times { stack << stack[-4] }
292
+ 2.times { stack.delete_at(-5) }
293
+ when OP_TUCK
294
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 2
295
+ stack.insert(-3, stack.last)
296
+ when OP_ABS
297
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 1
298
+ v = pop_int
299
+ push_int(v.abs)
300
+ when OP_BOOLAND
301
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 2
302
+ a, b = pop_int(2)
303
+ push_int((!a.zero? && !b.zero?) ? 1 : 0)
304
+ when OP_BOOLOR
305
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 2
306
+ a, b = pop_int(2)
307
+ push_int((!a.zero? || !b.zero?) ? 1 : 0)
308
+ when OP_NUMEQUAL, OP_NUMEQUALVERIFY
309
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 2
310
+ a, b = pop_int(2)
311
+ result = a == b
312
+ push_int(result ? 1 : 0)
313
+ if opcode == OP_NUMEQUALVERIFY
314
+ if result
315
+ stack.pop
316
+ else
317
+ return set_error(SCRIPT_ERR_NUMEQUALVERIFY)
205
318
  end
206
- when OP_DUP
207
- return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 1
208
- stack << stack.last
209
- when OP_2DUP
210
- return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 2
211
- 2.times { stack << stack[-2] }
212
- when OP_3DUP
213
- return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 3
214
- 3.times { stack << stack[-3] }
215
- when OP_IFDUP
216
- return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 1
217
- stack << stack.last if cast_to_bool(stack.last)
218
- when OP_RIPEMD160
219
- return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 1
220
- stack << Digest::RMD160.hexdigest(pop_string.htb)
221
- when OP_SHA1
222
- return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 1
223
- stack << Digest::SHA1.hexdigest(pop_string.htb)
224
- when OP_SHA256
225
- return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 1
226
- stack << Digest::SHA256.hexdigest(pop_string.htb)
227
- when OP_HASH160
228
- return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 1
229
- stack << Tapyrus.hash160(pop_string)
230
- when OP_HASH256
231
- return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 1
232
- stack << Tapyrus.double_sha256(pop_string.htb).bth
233
- when OP_VERIFY
234
- return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 1
235
- return set_error(SCRIPT_ERR_VERIFY) unless pop_bool
236
- when OP_TOALTSTACK
237
- return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 1
238
- alt_stack << stack.pop
239
- when OP_FROMALTSTACK
240
- return set_error(SCRIPT_ERR_INVALID_ALTSTACK_OPERATION) if alt_stack.size < 1
241
- stack << alt_stack.pop
242
- when OP_DROP
243
- return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 1
244
- stack.pop
245
- when OP_2DROP
246
- return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 2
247
- 2.times { stack.pop }
248
- when OP_NIP
249
- return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 2
250
- stack.delete_at(-2)
251
- when OP_OVER
252
- return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 2
253
- stack << stack[-2]
254
- when OP_2OVER
255
- return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 4
256
- 2.times { stack << stack[-4]}
257
- when OP_PICK, OP_ROLL
258
- return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 2
259
- pos = pop_int
260
- return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if pos < 0 || pos >= stack.size
261
- stack << stack[-pos - 1]
262
- stack.delete_at(-pos - 2) if opcode == OP_ROLL
263
- when OP_ROT
264
- return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 3
265
- stack << stack[-3]
266
- stack.delete_at(-4)
267
- when OP_2ROT
268
- return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 6
269
- 2.times { stack << stack[-6] }
270
- 2.times { stack.delete_at(-7) }
271
- when OP_SWAP
272
- return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 2
273
- tmp = stack.last
274
- stack[-1] = stack[-2]
275
- stack[-2] = tmp
276
- when OP_2SWAP
277
- return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 4
278
- 2.times {stack << stack[-4]}
279
- 2.times {stack.delete_at(-5)}
280
- when OP_TUCK
281
- return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 2
282
- stack.insert(-3, stack.last)
283
- when OP_ABS
284
- return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 1
285
- v = pop_int
286
- push_int(v.abs)
287
- when OP_BOOLAND
288
- return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 2
289
- a, b = pop_int(2)
290
- push_int((!a.zero? && !b.zero?) ? 1 : 0)
291
- when OP_BOOLOR
292
- return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 2
293
- a, b = pop_int(2)
294
- push_int((!a.zero? || !b.zero?) ? 1 : 0)
295
- when OP_NUMEQUAL, OP_NUMEQUALVERIFY
296
- return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 2
297
- a, b = pop_int(2)
298
- result = a == b
299
- push_int(result ? 1 : 0)
300
- if opcode == OP_NUMEQUALVERIFY
301
- if result
302
- stack.pop
303
- else
304
- return set_error(SCRIPT_ERR_NUMEQUALVERIFY)
305
- end
319
+ end
320
+ when OP_LESSTHAN, OP_LESSTHANOREQUAL
321
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 2
322
+ a, b = pop_int(2)
323
+ push_int(a < b ? 1 : 0) if opcode == OP_LESSTHAN
324
+ push_int(a <= b ? 1 : 0) if opcode == OP_LESSTHANOREQUAL
325
+ when OP_GREATERTHAN, OP_GREATERTHANOREQUAL
326
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 2
327
+ a, b = pop_int(2)
328
+ push_int(a > b ? 1 : 0) if opcode == OP_GREATERTHAN
329
+ push_int(a >= b ? 1 : 0) if opcode == OP_GREATERTHANOREQUAL
330
+ when OP_MIN
331
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 2
332
+ push_int(pop_int(2).min)
333
+ when OP_MAX
334
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 2
335
+ push_int(pop_int(2).max)
336
+ when OP_WITHIN
337
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 3
338
+ x, a, b = pop_int(3)
339
+ push_int((a <= x && x < b) ? 1 : 0)
340
+ when OP_NOT
341
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 1
342
+ push_int(pop_int == 0 ? 1 : 0)
343
+ when OP_SIZE
344
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 1
345
+ item = stack.last
346
+ item = Tapyrus::Script.encode_number(item) if item.is_a?(Numeric)
347
+ size = item.htb.bytesize
348
+ push_int(size)
349
+ when OP_NEGATE
350
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 1
351
+ push_int(-pop_int)
352
+ when OP_NUMNOTEQUAL
353
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 2
354
+ a, b = pop_int(2)
355
+ push_int(a == b ? 0 : 1)
356
+ when OP_CODESEPARATOR
357
+ last_code_separator_index = index + 1
358
+ when OP_CHECKSIG, OP_CHECKSIGVERIFY
359
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 2
360
+ sig, pubkey = pop_string(2)
361
+
362
+ subscript = script.subscript(last_code_separator_index..-1)
363
+ if sig_version == :base
364
+ tmp = subscript.find_and_delete(Script.new << sig)
365
+ if flag?(SCRIPT_VERIFY_CONST_SCRIPTCODE) && tmp != subscript
366
+ return set_error(SCRIPT_ERR_SIG_FINDANDDELETE)
306
367
  end
307
- when OP_LESSTHAN, OP_LESSTHANOREQUAL
308
- return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 2
309
- a, b = pop_int(2)
310
- push_int(a < b ? 1 : 0) if opcode == OP_LESSTHAN
311
- push_int(a <= b ? 1 : 0) if opcode == OP_LESSTHANOREQUAL
312
- when OP_GREATERTHAN, OP_GREATERTHANOREQUAL
313
- return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 2
314
- a, b = pop_int(2)
315
- push_int(a > b ? 1 : 0) if opcode == OP_GREATERTHAN
316
- push_int(a >= b ? 1 : 0) if opcode == OP_GREATERTHANOREQUAL
317
- when OP_MIN
318
- return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 2
319
- push_int(pop_int(2).min)
320
- when OP_MAX
321
- return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 2
322
- push_int(pop_int(2).max)
323
- when OP_WITHIN
324
- return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 3
325
- x, a, b = pop_int(3)
326
- push_int((a <= x && x < b) ? 1 : 0)
327
- when OP_NOT
328
- return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 1
329
- push_int(pop_int == 0 ? 1 : 0)
330
- when OP_SIZE
331
- return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 1
332
- item = stack.last
333
- item = Tapyrus::Script.encode_number(item) if item.is_a?(Numeric)
334
- size = item.htb.bytesize
335
- push_int(size)
336
- when OP_NEGATE
337
- return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 1
338
- push_int(-pop_int)
339
- when OP_NUMNOTEQUAL
340
- return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 2
341
- a, b = pop_int(2)
342
- push_int(a == b ? 0 : 1)
343
- when OP_CODESEPARATOR
344
- last_code_separator_index = index + 1
345
- when OP_CHECKSIG, OP_CHECKSIGVERIFY
346
- return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 2
347
- sig, pubkey = pop_string(2)
348
-
349
- subscript = script.subscript(last_code_separator_index..-1)
350
- if sig_version == :base
351
- tmp = subscript.find_and_delete(Script.new << sig)
352
- return set_error(SCRIPT_ERR_SIG_FINDANDDELETE) if flag?(SCRIPT_VERIFY_CONST_SCRIPTCODE) && tmp != subscript
353
- subscript = tmp
368
+ subscript = tmp
369
+ end
370
+ if (
371
+ if sig.htb.bytesize == Tapyrus::Key::COMPACT_SIGNATURE_SIZE
372
+ !check_schnorr_signature_encoding(sig)
373
+ else
374
+ !check_ecdsa_signature_encoding(sig)
375
+ end
376
+ ) || !check_pubkey_encoding(pubkey)
377
+ return false
378
+ end
379
+
380
+ success = checker.check_sig(sig, pubkey, subscript, sig_version)
381
+
382
+ # https://github.com/bitcoin/bips/blob/master/bip-0146.mediawiki#NULLFAIL
383
+ if !success && flag?(SCRIPT_VERIFY_NULLFAIL) && sig.bytesize > 0
384
+ return set_error(SCRIPT_ERR_SIG_NULLFAIL)
385
+ end
386
+
387
+ push_int(success ? 1 : 0)
388
+
389
+ if opcode == OP_CHECKSIGVERIFY
390
+ if success
391
+ stack.pop
392
+ else
393
+ return set_error(SCRIPT_ERR_CHECKSIGVERIFY)
354
394
  end
355
- return false if (sig.htb.bytesize == Tapyrus::Key::COMPACT_SIGNATURE_SIZE ?
356
- !check_schnorr_signature_encoding(sig) : !check_ecdsa_signature_encoding(sig)) || !check_pubkey_encoding(pubkey)
357
-
358
- success = checker.check_sig(sig, pubkey, subscript, sig_version)
359
-
360
- # https://github.com/bitcoin/bips/blob/master/bip-0146.mediawiki#NULLFAIL
361
- if !success && flag?(SCRIPT_VERIFY_NULLFAIL) && sig.bytesize > 0
362
- return set_error(SCRIPT_ERR_SIG_NULLFAIL)
363
- end
364
-
365
- push_int(success ? 1 : 0)
366
-
367
- if opcode == OP_CHECKSIGVERIFY
368
- if success
369
- stack.pop
370
- else
371
- return set_error(SCRIPT_ERR_CHECKSIGVERIFY)
372
- end
373
- end
374
- when OP_CHECKDATASIG, OP_CHECKDATASIGVERIFY
375
- return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 3
376
- sig, msg, pubkey = pop_string(3)
377
- # check signature encoding without hashtype byte
378
- return false if (sig.htb.bytesize != (Tapyrus::Key::COMPACT_SIGNATURE_SIZE - 1) && !check_ecdsa_signature_encoding(sig, true)) || !check_pubkey_encoding(pubkey)
379
- digest = Tapyrus.sha256(msg)
380
- success = checker.verify_sig(sig, pubkey, digest)
381
- return set_error(SCRIPT_ERR_SIG_NULLFAIL) if !success && flag?(SCRIPT_VERIFY_NULLFAIL) && sig.bytesize > 0
382
- push_int(success ? 1 : 0)
383
- if opcode == OP_CHECKDATASIGVERIFY
384
- stack.pop if success
385
- return set_error(SCRIPT_ERR_CHECKDATASIGVERIFY) unless success
386
- end
387
- when OP_CHECKMULTISIG, OP_CHECKMULTISIGVERIFY
388
- return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 1
389
- pubkey_count = pop_int
390
- unless (0..MAX_PUBKEYS_PER_MULTISIG).include?(pubkey_count)
391
- return set_error(SCRIPT_ERR_PUBKEY_COUNT)
392
- end
393
-
394
- op_count += pubkey_count
395
- return set_error(SCRIPT_ERR_OP_COUNT) if op_count > MAX_OPS_PER_SCRIPT
396
-
397
- return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < pubkey_count
398
-
399
- pubkeys = pop_string(pubkey_count)
400
- pubkeys = [pubkeys] if pubkeys.is_a?(String)
401
-
402
- return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 1
403
-
404
- sig_count = pop_int
405
- return set_error(SCRIPT_ERR_SIG_COUNT) if sig_count < 0 || sig_count > pubkey_count
406
- return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < (sig_count)
407
-
408
- sigs = pop_string(sig_count)
409
- sigs = [sigs] if sigs.is_a?(String)
410
-
411
- subscript = script.subscript(last_code_separator_index..-1)
412
-
413
- if sig_version == :base
414
- sigs.each do |sig|
415
- tmp = subscript.find_and_delete(Script.new << sig)
416
- return set_error(SCRIPT_ERR_SIG_FINDANDDELETE) if flag?(SCRIPT_VERIFY_CONST_SCRIPTCODE) && tmp != subscript
417
- subscript = tmp
395
+ end
396
+ when OP_CHECKDATASIG, OP_CHECKDATASIGVERIFY
397
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 3
398
+ sig, msg, pubkey = pop_string(3)
399
+
400
+ # check signature encoding without hashtype byte
401
+ if (
402
+ sig.htb.bytesize != (Tapyrus::Key::COMPACT_SIGNATURE_SIZE - 1) &&
403
+ !check_ecdsa_signature_encoding(sig, true)
404
+ ) || !check_pubkey_encoding(pubkey)
405
+ return false
406
+ end
407
+ digest = Tapyrus.sha256(msg)
408
+ success = checker.verify_sig(sig, pubkey, digest)
409
+ if !success && flag?(SCRIPT_VERIFY_NULLFAIL) && sig.bytesize > 0
410
+ return set_error(SCRIPT_ERR_SIG_NULLFAIL)
411
+ end
412
+ push_int(success ? 1 : 0)
413
+ if opcode == OP_CHECKDATASIGVERIFY
414
+ stack.pop if success
415
+ return set_error(SCRIPT_ERR_CHECKDATASIGVERIFY) unless success
416
+ end
417
+ when OP_CHECKMULTISIG, OP_CHECKMULTISIGVERIFY
418
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 1
419
+ pubkey_count = pop_int
420
+ return set_error(SCRIPT_ERR_PUBKEY_COUNT) unless (0..MAX_PUBKEYS_PER_MULTISIG).include?(pubkey_count)
421
+
422
+ op_count += pubkey_count
423
+ return set_error(SCRIPT_ERR_OP_COUNT) if op_count > MAX_OPS_PER_SCRIPT
424
+
425
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < pubkey_count
426
+
427
+ pubkeys = pop_string(pubkey_count)
428
+ pubkeys = [pubkeys] if pubkeys.is_a?(String)
429
+
430
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 1
431
+
432
+ sig_count = pop_int
433
+ return set_error(SCRIPT_ERR_SIG_COUNT) if sig_count < 0 || sig_count > pubkey_count
434
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < (sig_count)
435
+
436
+ sigs = pop_string(sig_count)
437
+ sigs = [sigs] if sigs.is_a?(String)
438
+
439
+ subscript = script.subscript(last_code_separator_index..-1)
440
+
441
+ if sig_version == :base
442
+ sigs.each do |sig|
443
+ tmp = subscript.find_and_delete(Script.new << sig)
444
+ if flag?(SCRIPT_VERIFY_CONST_SCRIPTCODE) && tmp != subscript
445
+ return set_error(SCRIPT_ERR_SIG_FINDANDDELETE)
418
446
  end
447
+ subscript = tmp
419
448
  end
420
-
421
- success = true
422
- current_sig_scheme = nil
423
- while success && sig_count > 0
424
- sig = sigs.pop
425
- pubkey = pubkeys.pop
426
- sig_scheme = sig.htb.bytesize == Tapyrus::Key::COMPACT_SIGNATURE_SIZE ? :schnorr : :ecdsa
427
- current_sig_scheme = sig_scheme if current_sig_scheme.nil?
428
-
429
- return false if (sig_scheme == :schnorr ? !check_schnorr_signature_encoding(sig) : !check_ecdsa_signature_encoding(sig)) || !check_pubkey_encoding(pubkey) # error already set.
430
-
431
- return set_error(SCRIPT_ERR_MIXED_SCHEME_MULTISIG) unless sig_scheme == current_sig_scheme
432
-
433
- ok = checker.check_sig(sig, pubkey, subscript, sig_version)
434
- if ok
435
- sig_count -= 1
436
- else
437
- sigs << sig
438
- end
439
- pubkey_count -= 1
440
- success = false if sig_count > pubkey_count
449
+ end
450
+
451
+ success = true
452
+ current_sig_scheme = nil
453
+ while success && sig_count > 0
454
+ sig = sigs.pop
455
+ pubkey = pubkeys.pop
456
+ sig_scheme = sig.htb.bytesize == Tapyrus::Key::COMPACT_SIGNATURE_SIZE ? :schnorr : :ecdsa
457
+ current_sig_scheme = sig_scheme if current_sig_scheme.nil?
458
+
459
+ if (
460
+ if sig_scheme == :schnorr
461
+ !check_schnorr_signature_encoding(sig)
462
+ else
463
+ !check_ecdsa_signature_encoding(sig)
464
+ end
465
+ ) || !check_pubkey_encoding(pubkey)
466
+ return false
467
+ end # error already set.
468
+
469
+ return set_error(SCRIPT_ERR_MIXED_SCHEME_MULTISIG) unless sig_scheme == current_sig_scheme
470
+
471
+ ok = checker.check_sig(sig, pubkey, subscript, sig_version)
472
+ if ok
473
+ sig_count -= 1
474
+ else
475
+ sigs << sig
441
476
  end
442
-
443
- if !success && flag?(SCRIPT_VERIFY_NULLFAIL)
444
- sigs.each do |sig|
445
- # If the operation failed, we require that all signatures must be empty vector
446
- return set_error(SCRIPT_ERR_SIG_NULLFAIL) if sig.bytesize > 0
447
- end
477
+ pubkey_count -= 1
478
+ success = false if sig_count > pubkey_count
479
+ end
480
+
481
+ if !success && flag?(SCRIPT_VERIFY_NULLFAIL)
482
+ sigs.each do |sig|
483
+ # If the operation failed, we require that all signatures must be empty vector
484
+ return set_error(SCRIPT_ERR_SIG_NULLFAIL) if sig.bytesize > 0
448
485
  end
449
-
450
- # A bug causes CHECKMULTISIG to consume one extra argument whose contents were not checked in any way.
451
- # Unfortunately this is a potential source of mutability,
452
- # so optionally verify it is exactly equal to zero prior to removing it from the stack.
453
- return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 1
454
- return set_error(SCRIPT_ERR_SIG_NULLDUMMY) if stack[-1].size > 0
455
-
456
- stack.pop
457
-
458
- push_int(success ? 1 : 0)
459
- if opcode == OP_CHECKMULTISIGVERIFY
460
- if success
461
- stack.pop
462
- else
463
- return set_error(SCRIPT_ERR_CHECKMULTISIGVERIFY)
464
- end
486
+ end
487
+
488
+ # A bug causes CHECKMULTISIG to consume one extra argument whose contents were not checked in any way.
489
+ # Unfortunately this is a potential source of mutability,
490
+ # so optionally verify it is exactly equal to zero prior to removing it from the stack.
491
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 1
492
+ return set_error(SCRIPT_ERR_SIG_NULLDUMMY) if stack[-1].size > 0
493
+
494
+ stack.pop
495
+
496
+ push_int(success ? 1 : 0)
497
+ if opcode == OP_CHECKMULTISIGVERIFY
498
+ if success
499
+ stack.pop
500
+ else
501
+ return set_error(SCRIPT_ERR_CHECKMULTISIGVERIFY)
465
502
  end
466
- when OP_RETURN
467
- return set_error(SCRIPT_ERR_OP_RETURN)
468
- when OP_COLOR
469
- # Color id is not permitted in p2sh redeem script
470
- return set_error(SCRIPT_ERR_OP_COLOR_UNEXPECTED) if is_redeem_script
503
+ end
504
+ when OP_RETURN
505
+ return set_error(SCRIPT_ERR_OP_RETURN)
506
+ when OP_COLOR
507
+ # Color id is not permitted in p2sh redeem script
508
+ return set_error(SCRIPT_ERR_OP_COLOR_UNEXPECTED) if is_redeem_script
471
509
 
472
- # if Color id is already initialized this must be an extra
473
- return set_error(SCRIPT_ERR_OP_COLOR_MULTIPLE) if color_id && color_id.type != Tapyrus::Color::TokenTypes::NONE
510
+ # if Color id is already initialized this must be an extra
511
+ if color_id && color_id.type != Tapyrus::Color::TokenTypes::NONE
512
+ return set_error(SCRIPT_ERR_OP_COLOR_MULTIPLE)
513
+ end
474
514
 
475
- # color id is not allowed inside OP_IF
476
- return set_error(SCRIPT_ERR_OP_COLOR_IN_BRANCH) unless flow_stack.empty?
515
+ # color id is not allowed inside OP_IF
516
+ return set_error(SCRIPT_ERR_OP_COLOR_IN_BRANCH) unless flow_stack.empty?
477
517
 
478
- # pop one stack element and verify that it exists
479
- return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size() < 1
518
+ # pop one stack element and verify that it exists
519
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 1
480
520
 
481
- color_id = Tapyrus::Color::ColorIdentifier.parse_from_payload(stack.last.htb)
521
+ color_id = Tapyrus::Color::ColorIdentifier.parse_from_payload(stack.last.htb)
482
522
 
483
- # check ColorIdentifier is valid
484
- return set_error(SCRIPT_ERR_OP_COLOR_ID_INVALID) unless color_id.valid?
523
+ # check ColorIdentifier is valid
524
+ return set_error(SCRIPT_ERR_OP_COLOR_ID_INVALID) unless color_id.valid?
485
525
 
486
- stack.pop
487
- else
488
- return set_error(SCRIPT_ERR_BAD_OPCODE)
526
+ stack.pop
527
+ else
528
+ return set_error(SCRIPT_ERR_BAD_OPCODE)
489
529
  end
490
530
  end
491
531
  end
@@ -513,7 +553,7 @@ module Tapyrus
513
553
 
514
554
  # pop the item with the int value for the number specified by +count+ from the stack.
515
555
  def pop_int(count = 1)
516
- i = stack.pop(count).map{ |s| cast_to_int(s) }
556
+ i = stack.pop(count).map { |s| cast_to_int(s) }
517
557
  count == 1 ? i.first : i
518
558
  end
519
559
 
@@ -536,14 +576,17 @@ module Tapyrus
536
576
 
537
577
  # pop the item with the string(hex) value for the number specified by +count+ from the stack.
538
578
  def pop_string(count = 1)
539
- s = stack.pop(count).map do |s|
540
- case s
541
- when Numeric
542
- Script.encode_number(s)
543
- else
544
- s
545
- end
546
- end
579
+ s =
580
+ stack
581
+ .pop(count)
582
+ .map do |s|
583
+ case s
584
+ when Numeric
585
+ Script.encode_number(s)
586
+ else
587
+ s
588
+ end
589
+ end
547
590
  count == 1 ? s.first : s
548
591
  end
549
592
 
@@ -555,15 +598,13 @@ module Tapyrus
555
598
  # see https://github.com/bitcoin/bitcoin/blob/master/src/script/interpreter.cpp#L36-L49
556
599
  def cast_to_bool(v)
557
600
  case v
558
- when Numeric
559
- return v != 0
560
- when String
561
- v.each_byte.with_index do |b, i|
562
- return !(i == (v.bytesize - 1) && b == 0x80) unless b == 0
563
- end
564
- false
565
- else
566
- false
601
+ when Numeric
602
+ return v != 0
603
+ when String
604
+ v.each_byte.with_index { |b, i| return !(i == (v.bytesize - 1) && b == 0x80) unless b == 0 }
605
+ false
606
+ else
607
+ false
567
608
  end
568
609
  end
569
610
 
@@ -616,7 +657,7 @@ module Tapyrus
616
657
  return opcode == data.bytesize
617
658
  elsif data.bytesize <= 255
618
659
  return opcode == OP_PUSHDATA1
619
- elsif data.bytesize <= 65535
660
+ elsif data.bytesize <= 65_535
620
661
  return opcode == OP_PUSHDATA2
621
662
  end
622
663
  true
@@ -626,22 +667,21 @@ module Tapyrus
626
667
  buf = StringIO.new(chunk)
627
668
  opcode = buf.read(1).ord
628
669
  offset = 1
629
- len = case opcode
630
- when OP_PUSHDATA1
631
- offset += 1
632
- buf.read(1).unpack('C').first
633
- when OP_PUSHDATA2
634
- offset += 2
635
- buf.read(2).unpack('v').first
636
- when OP_PUSHDATA4
637
- offset += 4
638
- buf.read(4).unpack('V').first
639
- else
640
- opcode
641
- end
670
+ len =
671
+ case opcode
672
+ when OP_PUSHDATA1
673
+ offset += 1
674
+ buf.read(1).unpack('C').first
675
+ when OP_PUSHDATA2
676
+ offset += 2
677
+ buf.read(2).unpack('v').first
678
+ when OP_PUSHDATA4
679
+ offset += 4
680
+ buf.read(4).unpack('V').first
681
+ else
682
+ opcode
683
+ end
642
684
  chunk.bytesize == len + offset
643
685
  end
644
-
645
686
  end
646
-
647
- end
687
+ end