tapyrus 0.2.13 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -2,13 +2,19 @@ module Tapyrus
2
2
  class ScriptInterpreter
3
3
  include Tapyrus::Opcodes
4
4
 
5
- attr_reader :stack
5
+ attr_accessor :stack
6
6
  attr_reader :debug
7
7
  attr_reader :flags
8
8
  attr_accessor :error
9
9
  attr_reader :checker
10
10
  attr_reader :require_minimal
11
11
 
12
+ attr_accessor :flow_stack
13
+ attr_accessor :alt_stack
14
+ attr_accessor :last_code_separator_index
15
+ attr_accessor :op_count
16
+ attr_accessor :color_id
17
+
12
18
  DISABLE_OPCODES = [
13
19
  OP_CAT,
14
20
  OP_SUBSTR,
@@ -51,11 +57,11 @@ module Tapyrus
51
57
 
52
58
  stack_copy = nil
53
59
 
54
- return false unless eval_script(script_sig, :base, false)
60
+ return false unless eval_script(script_sig, false)
55
61
 
56
62
  stack_copy = stack.dup if flag?(SCRIPT_VERIFY_P2SH)
57
63
 
58
- return false unless eval_script(script_pubkey, :base, false)
64
+ return false unless eval_script(script_pubkey, false)
59
65
 
60
66
  return set_error(SCRIPT_ERR_EVAL_FALSE) if stack.empty? || !cast_to_bool(stack.last.htb)
61
67
 
@@ -70,7 +76,7 @@ module Tapyrus
70
76
  rescue Exception => e
71
77
  return set_error(SCRIPT_ERR_BAD_OPCODE, "Failed to parse serialized redeem script for P2SH. #{e.message}")
72
78
  end
73
- return false unless eval_script(redeem_script, :base, true)
79
+ return false unless eval_script(redeem_script, true)
74
80
  return set_error(SCRIPT_ERR_EVAL_FALSE) if stack.empty? || !cast_to_bool(stack.last)
75
81
  end
76
82
 
@@ -92,457 +98,473 @@ module Tapyrus
92
98
  false
93
99
  end
94
100
 
95
- def eval_script(script, sig_version, is_redeem_script)
101
+ def eval_script(script, is_redeem_script)
96
102
  return set_error(SCRIPT_ERR_SCRIPT_SIZE) if script.size > MAX_SCRIPT_SIZE
97
103
  begin
98
- flow_stack = []
99
- alt_stack = []
100
- last_code_separator_index = 0
101
- op_count = 0
102
- color_id = nil
103
-
104
- script.chunks.each_with_index do |c, index|
105
- need_exec = !flow_stack.include?(false)
104
+ reset_params
105
+ script.chunks.each_with_index do |chunk, index|
106
+ result = next_step(script, chunk, index, is_redeem_script)
107
+ return result if result.is_a?(FalseClass)
108
+ end
109
+ rescue Exception => e
110
+ puts e
111
+ puts e.backtrace
112
+ return set_error(SCRIPT_ERR_UNKNOWN_ERROR, e.message)
113
+ end
106
114
 
107
- return set_error(SCRIPT_ERR_PUSH_SIZE) if c.pushdata? && c.pushed_data.bytesize > MAX_SCRIPT_ELEMENT_SIZE
115
+ return set_error(SCRIPT_ERR_UNBALANCED_CONDITIONAL) unless @flow_stack.empty?
108
116
 
109
- opcode = c.opcode
117
+ set_error(SCRIPT_ERR_OK)
118
+ true
119
+ end
110
120
 
111
- if need_exec && c.pushdata?
112
- return set_error(SCRIPT_ERR_MINIMALDATA) if require_minimal && !minimal_push?(c.pushed_data, opcode)
113
- return set_error(SCRIPT_ERR_BAD_OPCODE) unless verify_pushdata_length(c)
114
- stack << c.pushed_data.bth
115
- else
116
- if opcode > OP_16 && (op_count += 1) > MAX_OPS_PER_SCRIPT
117
- return set_error(SCRIPT_ERR_OP_COUNT)
118
- end
119
- return set_error(SCRIPT_ERR_DISABLED_OPCODE) if DISABLE_OPCODES.include?(opcode)
120
- if opcode == OP_CODESEPARATOR && sig_version == :base && flag?(SCRIPT_VERIFY_CONST_SCRIPTCODE)
121
- return set_error(SCRIPT_ERR_OP_CODESEPARATOR)
122
- end
123
- next unless (need_exec || (OP_IF <= opcode && opcode <= OP_ENDIF))
124
- small_int = Opcodes.opcode_to_small_int(opcode)
125
- if small_int && opcode != OP_0
126
- push_int(small_int)
127
- else
128
- case opcode
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)
143
- 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)
170
- end
171
- end
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)
318
- 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)
367
- end
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
121
+ def next_step(script, c, index, is_redeem_script)
122
+ need_exec = !@flow_stack.include?(false)
379
123
 
380
- success = checker.check_sig(sig, pubkey, subscript, sig_version)
124
+ return set_error(SCRIPT_ERR_PUSH_SIZE) if c.pushdata? && c.pushed_data.bytesize > MAX_SCRIPT_ELEMENT_SIZE
381
125
 
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
126
+ opcode = c.opcode
386
127
 
387
- push_int(success ? 1 : 0)
128
+ if need_exec && c.pushdata?
129
+ return set_error(SCRIPT_ERR_MINIMALDATA) if require_minimal && !minimal_push?(c.pushed_data, opcode)
130
+ return set_error(SCRIPT_ERR_BAD_OPCODE) unless verify_pushdata_length(c)
131
+ stack << c.pushed_data.bth
132
+ else
133
+ if opcode > OP_16 && (@op_count += 1) > MAX_OPS_PER_SCRIPT
134
+ return set_error(SCRIPT_ERR_OP_COUNT)
135
+ end
136
+ return set_error(SCRIPT_ERR_DISABLED_OPCODE) if DISABLE_OPCODES.include?(opcode)
137
+ if opcode == OP_CODESEPARATOR && flag?(SCRIPT_VERIFY_CONST_SCRIPTCODE)
138
+ return set_error(SCRIPT_ERR_OP_CODESEPARATOR)
139
+ end
388
140
 
389
- if opcode == OP_CHECKSIGVERIFY
390
- if success
391
- stack.pop
392
- else
393
- return set_error(SCRIPT_ERR_CHECKSIGVERIFY)
394
- end
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
141
+ # next unless (need_exec || (OP_IF <= opcode && opcode <= OP_ENDIF))
142
+ return unless (need_exec || (OP_IF <= opcode && opcode <= OP_ENDIF))
143
+ small_int = Opcodes.opcode_to_small_int(opcode)
144
+ if small_int && opcode != OP_0
145
+ push_int(small_int)
146
+ else
147
+ case opcode
148
+ when OP_0
149
+ stack << ''
150
+ when OP_DEPTH
151
+ push_int(stack.size)
152
+ when OP_EQUAL, OP_EQUALVERIFY
153
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 2
154
+ a, b = pop_string(2)
155
+ result = a == b
156
+ push_int(result ? 1 : 0)
157
+ if opcode == OP_EQUALVERIFY
158
+ if result
159
+ stack.pop
160
+ else
161
+ return set_error(SCRIPT_ERR_EQUALVERIFY)
162
+ end
163
+ end
164
+ when OP_0NOTEQUAL
165
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 1
166
+ push_int(pop_int == 0 ? 0 : 1)
167
+ when OP_ADD
168
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 2
169
+ a, b = pop_int(2)
170
+ push_int(a + b)
171
+ when OP_1ADD
172
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 1
173
+ push_int(pop_int + 1)
174
+ when OP_SUB
175
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 2
176
+ a, b = pop_int(2)
177
+ push_int(a - b)
178
+ when OP_1SUB
179
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 1
180
+ push_int(pop_int - 1)
181
+ when OP_IF, OP_NOTIF
182
+ result = false
183
+ if need_exec
184
+ return set_error(SCRIPT_ERR_UNBALANCED_CONDITIONAL) if stack.size < 1
185
+ value = pop_string.htb
186
+ if flag?(SCRIPT_VERIFY_MINIMALIF)
187
+ if value.bytesize > 1 || (value.bytesize == 1 && value[0].unpack('C').first != 1)
188
+ return set_error(SCRIPT_ERR_MINIMALIF)
416
189
  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
190
+ end
191
+ result = cast_to_bool(value)
192
+ result = !result if opcode == OP_NOTIF
193
+ end
194
+ @flow_stack << result
195
+ when OP_ELSE
196
+ return set_error(SCRIPT_ERR_UNBALANCED_CONDITIONAL) if @flow_stack.size < 1
197
+ @flow_stack << !@flow_stack.pop
198
+ when OP_ENDIF
199
+ return set_error(SCRIPT_ERR_UNBALANCED_CONDITIONAL) if @flow_stack.empty?
200
+ @flow_stack.pop
201
+ when OP_NOP
202
+ when OP_NOP1, OP_NOP4..OP_NOP10
203
+ return set_error(SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS) if flag?(SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS)
204
+ when OP_CHECKLOCKTIMEVERIFY
205
+ # next unless flag?(SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY)
206
+ return unless flag?(SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY)
207
+
208
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 1
209
+
210
+ # Note that elsewhere numeric opcodes are limited to operands in the range -2**31+1 to 2**31-1,
211
+ # however it is legal for opcodes to produce results exceeding that range.
212
+ # This limitation is implemented by CScriptNum's default 4-byte limit.
213
+ # If we kept to that limit we'd have a year 2038 problem,
214
+ # even though the nLockTime field in transactions themselves is uint32 which only becomes meaningless after the year 2106.
215
+ # Thus as a special case we tell CScriptNum to accept up to 5-byte bignums,
216
+ # which are good until 2**39-1, well beyond the 2**32-1 limit of the nLockTime field itself.
217
+ locktime = cast_to_int(stack.last, 5)
218
+ return set_error(SCRIPT_ERR_NEGATIVE_LOCKTIME) if locktime < 0
219
+ return set_error(SCRIPT_ERR_UNSATISFIED_LOCKTIME) unless checker.check_locktime(locktime)
220
+ when OP_CHECKSEQUENCEVERIFY
221
+ # next unless flag?(SCRIPT_VERIFY_CHECKSEQUENCEVERIFY)
222
+ return unless flag?(SCRIPT_VERIFY_CHECKSEQUENCEVERIFY)
223
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 1
224
+
225
+ # nSequence, like nLockTime, is a 32-bit unsigned integer field.
226
+ # See the comment in CHECKLOCKTIMEVERIFY regarding 5-byte numeric operands.
227
+ sequence = cast_to_int(stack.last, 5)
228
+
229
+ # In the rare event that the argument may be < 0 due to some arithmetic being done first,
230
+ # you can always use 0 MAX CHECKSEQUENCEVERIFY.
231
+ return set_error(SCRIPT_ERR_NEGATIVE_LOCKTIME) if sequence < 0
232
+
233
+ # To provide for future soft-fork extensibility,
234
+ # if the operand has the disabled lock-time flag set, CHECKSEQUENCEVERIFY behaves as a NOP.
235
+ # next if (sequence & Tapyrus::TxIn::SEQUENCE_LOCKTIME_DISABLE_FLAG) != 0
236
+ return if (sequence & Tapyrus::TxIn::SEQUENCE_LOCKTIME_DISABLE_FLAG) != 0
237
+
238
+ # Compare the specified sequence number with the input.
239
+ return set_error(SCRIPT_ERR_UNSATISFIED_LOCKTIME) unless checker.check_sequence(sequence)
240
+ when OP_DUP
241
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 1
242
+ stack << stack.last
243
+ when OP_2DUP
244
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 2
245
+ 2.times { stack << stack[-2] }
246
+ when OP_3DUP
247
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 3
248
+ 3.times { stack << stack[-3] }
249
+ when OP_IFDUP
250
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 1
251
+ stack << stack.last if cast_to_bool(stack.last)
252
+ when OP_RIPEMD160
253
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 1
254
+ stack << Digest::RMD160.hexdigest(pop_string.htb)
255
+ when OP_SHA1
256
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 1
257
+ stack << Digest::SHA1.hexdigest(pop_string.htb)
258
+ when OP_SHA256
259
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 1
260
+ stack << Digest::SHA256.hexdigest(pop_string.htb)
261
+ when OP_HASH160
262
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 1
263
+ stack << Tapyrus.hash160(pop_string)
264
+ when OP_HASH256
265
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 1
266
+ stack << Tapyrus.double_sha256(pop_string.htb).bth
267
+ when OP_VERIFY
268
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 1
269
+ return set_error(SCRIPT_ERR_VERIFY) unless pop_bool
270
+ when OP_TOALTSTACK
271
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 1
272
+ @alt_stack << stack.pop
273
+ when OP_FROMALTSTACK
274
+ return set_error(SCRIPT_ERR_INVALID_ALTSTACK_OPERATION) if @alt_stack.size < 1
275
+ stack << @alt_stack.pop
276
+ when OP_DROP
277
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 1
278
+ stack.pop
279
+ when OP_2DROP
280
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 2
281
+ 2.times { stack.pop }
282
+ when OP_NIP
283
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 2
284
+ stack.delete_at(-2)
285
+ when OP_OVER
286
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 2
287
+ stack << stack[-2]
288
+ when OP_2OVER
289
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 4
290
+ 2.times { stack << stack[-4] }
291
+ when OP_PICK, OP_ROLL
292
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 2
293
+ pos = pop_int
294
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if pos < 0 || pos >= stack.size
295
+ stack << stack[-pos - 1]
296
+ stack.delete_at(-pos - 2) if opcode == OP_ROLL
297
+ when OP_ROT
298
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 3
299
+ stack << stack[-3]
300
+ stack.delete_at(-4)
301
+ when OP_2ROT
302
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 6
303
+ 2.times { stack << stack[-6] }
304
+ 2.times { stack.delete_at(-7) }
305
+ when OP_SWAP
306
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 2
307
+ tmp = stack.last
308
+ stack[-1] = stack[-2]
309
+ stack[-2] = tmp
310
+ when OP_2SWAP
311
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 4
312
+ 2.times { stack << stack[-4] }
313
+ 2.times { stack.delete_at(-5) }
314
+ when OP_TUCK
315
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 2
316
+ stack.insert(-3, stack.last)
317
+ when OP_ABS
318
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 1
319
+ v = pop_int
320
+ push_int(v.abs)
321
+ when OP_BOOLAND
322
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 2
323
+ a, b = pop_int(2)
324
+ push_int((!a.zero? && !b.zero?) ? 1 : 0)
325
+ when OP_BOOLOR
326
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 2
327
+ a, b = pop_int(2)
328
+ push_int((!a.zero? || !b.zero?) ? 1 : 0)
329
+ when OP_NUMEQUAL, OP_NUMEQUALVERIFY
330
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 2
331
+ a, b = pop_int(2)
332
+ result = a == b
333
+ push_int(result ? 1 : 0)
334
+ if opcode == OP_NUMEQUALVERIFY
335
+ if result
336
+ stack.pop
337
+ else
338
+ return set_error(SCRIPT_ERR_NUMEQUALVERIFY)
339
+ end
340
+ end
341
+ when OP_LESSTHAN, OP_LESSTHANOREQUAL
342
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 2
343
+ a, b = pop_int(2)
344
+ push_int(a < b ? 1 : 0) if opcode == OP_LESSTHAN
345
+ push_int(a <= b ? 1 : 0) if opcode == OP_LESSTHANOREQUAL
346
+ when OP_GREATERTHAN, OP_GREATERTHANOREQUAL
347
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 2
348
+ a, b = pop_int(2)
349
+ push_int(a > b ? 1 : 0) if opcode == OP_GREATERTHAN
350
+ push_int(a >= b ? 1 : 0) if opcode == OP_GREATERTHANOREQUAL
351
+ when OP_MIN
352
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 2
353
+ push_int(pop_int(2).min)
354
+ when OP_MAX
355
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 2
356
+ push_int(pop_int(2).max)
357
+ when OP_WITHIN
358
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 3
359
+ x, a, b = pop_int(3)
360
+ push_int((a <= x && x < b) ? 1 : 0)
361
+ when OP_NOT
362
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 1
363
+ push_int(pop_int == 0 ? 1 : 0)
364
+ when OP_SIZE
365
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 1
366
+ item = stack.last
367
+ item = Tapyrus::Script.encode_number(item) if item.is_a?(Numeric)
368
+ size = item.htb.bytesize
369
+ push_int(size)
370
+ when OP_NEGATE
371
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 1
372
+ push_int(-pop_int)
373
+ when OP_NUMNOTEQUAL
374
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 2
375
+ a, b = pop_int(2)
376
+ push_int(a == b ? 0 : 1)
377
+ when OP_CODESEPARATOR
378
+ @last_code_separator_index = index + 1
379
+ when OP_CHECKSIG, OP_CHECKSIGVERIFY
380
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 2
381
+ sig, pubkey = pop_string(2)
382
+
383
+ subscript = script.subscript(@last_code_separator_index..-1)
384
+ tmp = subscript.find_and_delete(Script.new << sig)
385
+ return set_error(SCRIPT_ERR_SIG_FINDANDDELETE) if flag?(SCRIPT_VERIFY_CONST_SCRIPTCODE) && tmp != subscript
386
+ subscript = tmp
387
+
388
+ if (
389
+ if sig.htb.bytesize == Tapyrus::Key::COMPACT_SIGNATURE_SIZE
390
+ !check_schnorr_signature_encoding(sig)
391
+ else
392
+ !check_ecdsa_signature_encoding(sig)
393
+ end
394
+ ) || !check_pubkey_encoding(pubkey)
395
+ return false
396
+ end
424
397
 
425
- return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < pubkey_count
398
+ success = checker.check_sig(sig, pubkey, subscript)
426
399
 
427
- pubkeys = pop_string(pubkey_count)
428
- pubkeys = [pubkeys] if pubkeys.is_a?(String)
400
+ # https://github.com/bitcoin/bips/blob/master/bip-0146.mediawiki#NULLFAIL
401
+ return set_error(SCRIPT_ERR_SIG_NULLFAIL) if !success && flag?(SCRIPT_VERIFY_NULLFAIL) && sig.bytesize > 0
429
402
 
430
- return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 1
403
+ push_int(success ? 1 : 0)
431
404
 
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)
405
+ if opcode == OP_CHECKSIGVERIFY
406
+ if success
407
+ stack.pop
408
+ else
409
+ return set_error(SCRIPT_ERR_CHECKSIGVERIFY)
410
+ end
411
+ end
412
+ when OP_CHECKDATASIG, OP_CHECKDATASIGVERIFY
413
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 3
414
+ sig, msg, pubkey = pop_string(3)
415
+
416
+ # check signature encoding without hashtype byte
417
+ if (
418
+ sig.htb.bytesize != (Tapyrus::Key::COMPACT_SIGNATURE_SIZE - 1) &&
419
+ !check_ecdsa_signature_encoding(sig, true)
420
+ ) || !check_pubkey_encoding(pubkey)
421
+ return false
422
+ end
423
+ digest = Tapyrus.sha256(msg)
424
+ success = checker.verify_sig(sig, pubkey, digest)
425
+ return set_error(SCRIPT_ERR_SIG_NULLFAIL) if !success && flag?(SCRIPT_VERIFY_NULLFAIL) && sig.bytesize > 0
426
+ push_int(success ? 1 : 0)
427
+ if opcode == OP_CHECKDATASIGVERIFY
428
+ stack.pop if success
429
+ return set_error(SCRIPT_ERR_CHECKDATASIGVERIFY) unless success
430
+ end
431
+ when OP_CHECKMULTISIG, OP_CHECKMULTISIGVERIFY
432
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 1
433
+ pubkey_count = pop_int
434
+ return set_error(SCRIPT_ERR_PUBKEY_COUNT) unless (0..MAX_PUBKEYS_PER_MULTISIG).include?(pubkey_count)
435
435
 
436
- sigs = pop_string(sig_count)
437
- sigs = [sigs] if sigs.is_a?(String)
436
+ @op_count += pubkey_count
437
+ return set_error(SCRIPT_ERR_OP_COUNT) if @op_count > MAX_OPS_PER_SCRIPT
438
438
 
439
- subscript = script.subscript(last_code_separator_index..-1)
439
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < pubkey_count
440
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)
446
- end
447
- subscript = tmp
448
- end
449
- end
441
+ pubkeys = pop_string(pubkey_count)
442
+ pubkeys = [pubkeys] if pubkeys.is_a?(String)
450
443
 
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
476
- end
477
- pubkey_count -= 1
478
- success = false if sig_count > pubkey_count
479
- end
444
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 1
480
445
 
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
485
- end
486
- end
446
+ sig_count = pop_int
447
+ return set_error(SCRIPT_ERR_SIG_COUNT) if sig_count < 0 || sig_count > pubkey_count
448
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < (sig_count)
487
449
 
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
450
+ sigs = pop_string(sig_count)
451
+ sigs = [sigs] if sigs.is_a?(String)
493
452
 
494
- stack.pop
453
+ subscript = script.subscript(@last_code_separator_index..-1)
495
454
 
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)
502
- end
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
509
-
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
455
+ sigs.each do |sig|
456
+ tmp = subscript.find_and_delete(Script.new << sig)
457
+ if flag?(SCRIPT_VERIFY_CONST_SCRIPTCODE) && tmp != subscript
458
+ return set_error(SCRIPT_ERR_SIG_FINDANDDELETE)
459
+ end
460
+ subscript = tmp
461
+ end
514
462
 
515
- # color id is not allowed inside OP_IF
516
- return set_error(SCRIPT_ERR_OP_COLOR_IN_BRANCH) unless flow_stack.empty?
463
+ success = true
464
+ current_sig_scheme = nil
465
+ while success && sig_count > 0
466
+ sig = sigs.pop
467
+ pubkey = pubkeys.pop
468
+ sig_scheme = sig.htb.bytesize == Tapyrus::Key::COMPACT_SIGNATURE_SIZE ? :schnorr : :ecdsa
469
+ current_sig_scheme = sig_scheme if current_sig_scheme.nil?
470
+
471
+ if (
472
+ if sig_scheme == :schnorr
473
+ !check_schnorr_signature_encoding(sig)
474
+ else
475
+ !check_ecdsa_signature_encoding(sig)
476
+ end
477
+ ) || !check_pubkey_encoding(pubkey)
478
+ return false
479
+ end # error already set.
480
+
481
+ return set_error(SCRIPT_ERR_MIXED_SCHEME_MULTISIG) unless sig_scheme == current_sig_scheme
482
+
483
+ ok = checker.check_sig(sig, pubkey, subscript)
484
+ if ok
485
+ sig_count -= 1
486
+ else
487
+ sigs << sig
488
+ end
489
+ pubkey_count -= 1
490
+ success = false if sig_count > pubkey_count
491
+ end
517
492
 
518
- # pop one stack element and verify that it exists
519
- return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 1
493
+ if !success && flag?(SCRIPT_VERIFY_NULLFAIL)
494
+ sigs.each do |sig|
495
+ # If the operation failed, we require that all signatures must be empty vector
496
+ return set_error(SCRIPT_ERR_SIG_NULLFAIL) if sig.bytesize > 0
497
+ end
498
+ end
520
499
 
521
- color_id = Tapyrus::Color::ColorIdentifier.parse_from_payload(stack.last.htb)
500
+ # A bug causes CHECKMULTISIG to consume one extra argument whose contents were not checked in any way.
501
+ # Unfortunately this is a potential source of mutability,
502
+ # so optionally verify it is exactly equal to zero prior to removing it from the stack.
503
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 1
504
+ return set_error(SCRIPT_ERR_SIG_NULLDUMMY) if stack[-1].size > 0
522
505
 
523
- # check ColorIdentifier is valid
524
- return set_error(SCRIPT_ERR_OP_COLOR_ID_INVALID) unless color_id.valid?
506
+ stack.pop
525
507
 
508
+ push_int(success ? 1 : 0)
509
+ if opcode == OP_CHECKMULTISIGVERIFY
510
+ if success
526
511
  stack.pop
527
512
  else
528
- return set_error(SCRIPT_ERR_BAD_OPCODE)
513
+ return set_error(SCRIPT_ERR_CHECKMULTISIGVERIFY)
529
514
  end
530
515
  end
531
- end
516
+ when OP_RETURN
517
+ return set_error(SCRIPT_ERR_OP_RETURN)
518
+ when OP_COLOR
519
+ # Color id is not permitted in p2sh redeem script
520
+ return set_error(SCRIPT_ERR_OP_COLOR_UNEXPECTED) if is_redeem_script
521
+
522
+ # if Color id is already initialized this must be an extra
523
+ if @color_id && @color_id.type != Tapyrus::Color::TokenTypes::NONE
524
+ return set_error(SCRIPT_ERR_OP_COLOR_MULTIPLE)
525
+ end
526
+
527
+ # color id is not allowed inside OP_IF
528
+ return set_error(SCRIPT_ERR_OP_COLOR_IN_BRANCH) unless @flow_stack.empty?
532
529
 
533
- # max stack size check
534
- return set_error(SCRIPT_ERR_STACK_SIZE) if stack.size + alt_stack.size > MAX_STACK_SIZE
530
+ # pop one stack element and verify that it exists
531
+ return set_error(SCRIPT_ERR_INVALID_STACK_OPERATION) if stack.size < 1
532
+
533
+ @color_id = Tapyrus::Color::ColorIdentifier.parse_from_payload(stack.last.htb)
534
+
535
+ # check ColorIdentifier is valid
536
+ return set_error(SCRIPT_ERR_OP_COLOR_ID_INVALID) unless @color_id.valid?
537
+
538
+ stack.pop
539
+ else
540
+ return set_error(SCRIPT_ERR_BAD_OPCODE)
541
+ end
535
542
  end
536
- rescue Exception => e
537
- puts e
538
- puts e.backtrace
539
- return set_error(SCRIPT_ERR_UNKNOWN_ERROR, e.message)
540
543
  end
541
544
 
542
- return set_error(SCRIPT_ERR_UNBALANCED_CONDITIONAL) unless flow_stack.empty?
545
+ # max stack size check
546
+ return set_error(SCRIPT_ERR_STACK_SIZE) if stack.size + @alt_stack.size > MAX_STACK_SIZE
547
+ end
543
548
 
544
- set_error(SCRIPT_ERR_OK)
545
- true
549
+ def reset_params
550
+ @flow_stack = []
551
+ @alt_stack = []
552
+ @last_code_separator_index = 0
553
+ @op_count = 0
554
+ @color_id = nil
555
+ end
556
+
557
+ # see https://github.com/bitcoin/bitcoin/blob/master/src/script/interpreter.cpp#L36-L49
558
+ def cast_to_bool(v)
559
+ case v
560
+ when Numeric
561
+ return v != 0
562
+ when String
563
+ v.each_byte.with_index { |b, i| return !(i == (v.bytesize - 1) && b == 0x80) unless b == 0 }
564
+ false
565
+ else
566
+ false
567
+ end
546
568
  end
547
569
 
548
570
  private
@@ -595,19 +617,6 @@ module Tapyrus
595
617
  cast_to_bool(pop_string.htb)
596
618
  end
597
619
 
598
- # see https://github.com/bitcoin/bitcoin/blob/master/src/script/interpreter.cpp#L36-L49
599
- def cast_to_bool(v)
600
- case v
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
608
- end
609
- end
610
-
611
620
  def check_ecdsa_signature_encoding(sig, data_sig = false)
612
621
  return true if sig.size.zero?
613
622
  if !Key.valid_signature_encoding?(sig.htb, data_sig)