tapyrus 0.2.7 → 0.2.8

Sign up to get free protection for your applications and to get access to all the features.
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 +6 -22
  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 +10 -0
  85. data/lib/tapyrus/script/multisig.rb +13 -12
  86. data/lib/tapyrus/script/script.rb +72 -71
  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 +14 -15
  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 +7 -9
  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 -14
  114. metadata +21 -4
  115. data/.travis.yml +0 -14
@@ -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