monacoin-ruby 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,142 @@
1
+ # encoding: ascii-8bit
2
+
3
+ module Bitcoin
4
+ module Protocol
5
+
6
+ class TxIn
7
+
8
+ # previous output hash
9
+ attr_accessor :prev_out_hash
10
+ alias :prev_out :prev_out_hash
11
+ def prev_out=(hash); @prev_out_hash = hash; end
12
+
13
+ # previous output index
14
+ attr_accessor :prev_out_index
15
+
16
+ # script_sig input Script (signature)
17
+ attr_accessor :script_sig, :script_sig_length
18
+
19
+ # signature hash and the address of the key that needs to sign it
20
+ # (used when dealing with unsigned or partly signed tx)
21
+ attr_accessor :sig_hash, :sig_address
22
+
23
+ # segregated witness
24
+ attr_accessor :script_witness
25
+
26
+ alias :script :script_sig
27
+ alias :script_length :script_sig_length
28
+
29
+ # sequence
30
+ attr_accessor :sequence
31
+
32
+ DEFAULT_SEQUENCE = "\xff\xff\xff\xff"
33
+ NULL_HASH = "\x00"*32
34
+ COINBASE_INDEX = 0xffffffff
35
+
36
+ def initialize *args
37
+ @prev_out_hash, @prev_out_index, @script_sig_length,
38
+ @script_sig, @sequence = *args
39
+ @script_sig_length ||= 0
40
+ @script_sig ||= ''
41
+ @sequence ||= DEFAULT_SEQUENCE
42
+ @script_witness = ScriptWitness.new
43
+ end
44
+
45
+ # compare to another txout
46
+ def ==(other)
47
+ @prev_out_hash == other.prev_out_hash &&
48
+ @prev_out_index == other.prev_out_index &&
49
+ @script_sig == other.script_sig &&
50
+ @sequence == other.sequence
51
+ rescue
52
+ false
53
+ end
54
+
55
+ # returns true if the sequence number is final (DEFAULT_SEQUENCE)
56
+ def is_final?
57
+ self.sequence == DEFAULT_SEQUENCE
58
+ end
59
+
60
+ # parse raw binary data for transaction input
61
+ def parse_data(data)
62
+ buf = data.is_a?(String) ? StringIO.new(data) : data
63
+ parse_data_from_io(buf)
64
+ buf.pos
65
+ end
66
+
67
+ def self.from_io(buf)
68
+ txin = new; txin.parse_data_from_io(buf); txin
69
+ end
70
+
71
+ def parse_data_from_io(buf)
72
+ @prev_out_hash, @prev_out_index = buf.read(36).unpack("a32V")
73
+ @script_sig_length = Protocol.unpack_var_int_from_io(buf)
74
+ @script_sig = buf.read(@script_sig_length)
75
+ @sequence = buf.read(4)
76
+ end
77
+
78
+ def parsed_script
79
+ @parsed_script ||= Bitcoin::Script.new(script_sig)
80
+ end
81
+
82
+ def to_payload(script=@script_sig, sequence=@sequence)
83
+ [@prev_out_hash, @prev_out_index].pack("a32V") << Protocol.pack_var_int(script.bytesize) << script << (sequence || DEFAULT_SEQUENCE)
84
+ end
85
+
86
+ def to_hash(options = {})
87
+ t = { 'prev_out' => { 'hash' => @prev_out_hash.reverse_hth, 'n' => @prev_out_index } }
88
+ if coinbase?
89
+ t['coinbase'] = @script_sig.unpack("H*")[0]
90
+ else # coinbase tx
91
+ t['scriptSig'] = Bitcoin::Script.new(@script_sig).to_string
92
+ end
93
+ t['sequence'] = @sequence.unpack("V")[0] unless @sequence == "\xff\xff\xff\xff"
94
+ t['witness'] = @script_witness.stack.map{|s|s.bth} unless @script_witness.empty?
95
+ t
96
+ end
97
+
98
+ def self.from_hash(input)
99
+ previous_hash = input['previous_transaction_hash'] || input['prev_out']['hash']
100
+ previous_output_index = input['output_index'] || input['prev_out']['n']
101
+ txin = TxIn.new([ previous_hash ].pack('H*').reverse, previous_output_index)
102
+ if input['coinbase']
103
+ txin.script_sig = [ input['coinbase'] ].pack("H*")
104
+ else
105
+ txin.script_sig = Script.binary_from_string(input['scriptSig'] || input['script'])
106
+ end
107
+ if input['witness']
108
+ input['witness'].each {|w| txin.script_witness.stack << w.htb}
109
+ end
110
+ txin.sequence = [ input['sequence'] || 0xffffffff ].pack("V")
111
+ txin
112
+ end
113
+
114
+ def self.from_hex_hash(hash, index)
115
+ TxIn.new([hash].pack("H*").reverse, index, 0)
116
+ end
117
+
118
+ # previous output in hex
119
+ def previous_output
120
+ @prev_out_hash.reverse_hth
121
+ end
122
+
123
+ # check if input is coinbase
124
+ def coinbase?
125
+ (@prev_out_index == COINBASE_INDEX) && (@prev_out_hash == NULL_HASH)
126
+ end
127
+
128
+ # set script_sig and script_sig_length
129
+ def script_sig=(script_sig)
130
+ @script_sig_length = script_sig.bytesize
131
+ @script_sig = script_sig
132
+ end
133
+ alias :script= :script_sig=
134
+
135
+ def add_signature_pubkey_script(sig, pubkey_hex)
136
+ self.script = Bitcoin::Script.to_signature_pubkey_script(sig, [pubkey_hex].pack("H*"))
137
+ end
138
+
139
+ end
140
+
141
+ end
142
+ end
@@ -0,0 +1,95 @@
1
+ # encoding: ascii-8bit
2
+
3
+ module Bitcoin
4
+ module Protocol
5
+
6
+ class TxOut
7
+
8
+ # output value (in base units; "satoshi")
9
+ attr_accessor :value
10
+
11
+ # pk_script output Script
12
+ attr_accessor :pk_script, :pk_script_length
13
+
14
+ # p2sh redeem script (optional, not included in the serialized binary format)
15
+ attr_accessor :redeem_script
16
+
17
+ def initialize *args
18
+ if args.size == 2
19
+ @value, @pk_script_length, @pk_script = args[0], args[1].bytesize, args[1]
20
+ else
21
+ @value, @pk_script_length, @pk_script = *args
22
+ end
23
+ end
24
+
25
+ def ==(other)
26
+ @value == other.value && @pk_script == other.pk_script rescue false
27
+ end
28
+
29
+ # parse raw binary data for transaction output
30
+ def parse_data(data)
31
+ buf = data.is_a?(String) ? StringIO.new(data) : data
32
+ parse_data_from_io(buf)
33
+ buf.pos
34
+ end
35
+
36
+ def self.from_io(buf)
37
+ txout = new; txout.parse_data_from_io(buf); txout
38
+ end
39
+
40
+ # parse raw binary data for transaction output
41
+ def parse_data_from_io(buf)
42
+ @value = buf.read(8).unpack("Q")[0]
43
+ @pk_script_length = Protocol.unpack_var_int_from_io(buf)
44
+ @pk_script = buf.read(@pk_script_length)
45
+ end
46
+
47
+ alias :parse_payload :parse_data
48
+
49
+ def parsed_script
50
+ @parsed_script ||= Bitcoin::Script.new(pk_script)
51
+ end
52
+
53
+ def to_payload
54
+ [@value].pack("Q") << Protocol.pack_var_int(@pk_script_length) << @pk_script
55
+ end
56
+
57
+ def to_null_payload
58
+ self.class.new(-1, '').to_payload
59
+ end
60
+
61
+ def to_hash(options = {})
62
+ h = { 'value' => "%.8f" % (@value / 100000000.0),
63
+ 'scriptPubKey' => parsed_script.to_string }
64
+ h["address"] = parsed_script.get_address if parsed_script.is_hash160? && options[:with_address]
65
+ h
66
+ end
67
+
68
+ def self.from_hash(output)
69
+ amount = output['value'] ? output['value'].gsub('.','').to_i : output['amount']
70
+ script = Script.binary_from_string(output['scriptPubKey'] || output['script'])
71
+ new(amount, script)
72
+ end
73
+
74
+ # set pk_script and pk_script_length
75
+ def pk_script=(pk_script)
76
+ @pk_script_length, @pk_script = pk_script.bytesize, pk_script
77
+ end
78
+
79
+ alias :amount :value
80
+ alias :amount= :value=
81
+
82
+ alias :script :pk_script
83
+ alias :script= :pk_script=
84
+
85
+ # create output spending +value+ btc (base units) to +address+
86
+ def self.value_to_address(value, address)
87
+ pk_script = Bitcoin::Script.to_address_script(address)
88
+ raise "Script#pk_script nil with address #{address}" unless pk_script
89
+ new(value, pk_script)
90
+ end
91
+
92
+ end
93
+
94
+ end
95
+ end
@@ -0,0 +1,88 @@
1
+ # encoding: ascii-8bit
2
+
3
+ module Bitcoin
4
+ module Protocol
5
+
6
+ # https://en.bitcoin.it/wiki/Protocol_specification#version
7
+ class Version
8
+ # services bit constants
9
+ NODE_NONE = 0
10
+ NODE_NETWORK = (1 << 0)
11
+
12
+ attr_reader :fields
13
+
14
+ def initialize(opts={})
15
+ @fields = {
16
+ :version => Bitcoin.network[:protocol_version],
17
+ :services => NODE_NETWORK,
18
+ :time => Time.now.tv_sec,
19
+ :from => "127.0.0.1:8333",
20
+ :to => "127.0.0.1:8333",
21
+ :nonce => Bitcoin::Protocol::Uniq,
22
+ :user_agent => "/bitcoin-ruby:#{Bitcoin::VERSION}/",
23
+ :last_block => 0, # 188617
24
+ :relay => true # BIP0037
25
+ }.merge( opts.reject{|k,v| v == nil } )
26
+ end
27
+
28
+ def to_payload
29
+ [
30
+ @fields.values_at(:version, :services, :time).pack("VQQ"),
31
+ pack_address_field(@fields[:from]),
32
+ pack_address_field(@fields[:to]),
33
+ @fields.values_at(:nonce).pack("Q"),
34
+ Protocol.pack_var_string(@fields[:user_agent]),
35
+ @fields.values_at(:last_block).pack("V"),
36
+ Protocol.pack_boolean(@fields[:relay]) # Satoshi 0.8.6 doesn't send this but it does respect it
37
+ ].join
38
+ end
39
+
40
+ def to_pkt
41
+ Bitcoin::Protocol.pkt("version", to_payload)
42
+ end
43
+
44
+ def parse(payload)
45
+ version, services, timestamp, to, from, nonce, payload = payload.unpack("VQQa26a26Qa*")
46
+ to, from = unpack_address_field(to), unpack_address_field(from)
47
+ user_agent, payload = Protocol.unpack_var_string(payload)
48
+ last_block, payload = payload.unpack("Va*")
49
+ relay, payload = unpack_relay_field(version, payload)
50
+
51
+ @fields = {
52
+ :version => version, :services => services, :time => timestamp,
53
+ :from => from, :to => to, :nonce => nonce,
54
+ :user_agent => user_agent.to_s, :last_block => last_block, :relay => relay
55
+ }
56
+ self
57
+ end
58
+
59
+ def unpack_address_field(payload)
60
+ ip, port = payload.unpack("x8x12a4n")
61
+ "#{ip.unpack("C*").join(".")}:#{port}"
62
+ end
63
+
64
+ def pack_address_field(addr_str)
65
+ host, port = addr_str.split(":")
66
+ port = port ? port.to_i : 8333
67
+ sockaddr = Socket.pack_sockaddr_in(port, host)
68
+ #raise "invalid IPv4 Address: #{addr}" unless sockaddr[0...2] == "\x02\x00"
69
+ port, host = sockaddr[2...4], sockaddr[4...8]
70
+ [[1].pack("Q"), "\x00"*10, "\xFF\xFF", host, port].join
71
+ end
72
+
73
+ # BIP0037: this field starts with version 70001 and is allowed to be missing, defaults to true
74
+ def unpack_relay_field(version, payload)
75
+ ( version >= 70001 and payload ) ? Protocol.unpack_boolean(payload) : [ true, nil ]
76
+ end
77
+
78
+ def uptime
79
+ @fields[:time] - Time.now.tv_sec
80
+ end
81
+
82
+ def method_missing(*a); (@fields[a.first] rescue nil) or super(*a); end
83
+
84
+ def self.parse(payload); new.parse(payload); end
85
+ end
86
+
87
+ end
88
+ end
@@ -0,0 +1,1656 @@
1
+ # encoding: ascii-8bit
2
+
3
+ require 'bitcoin'
4
+
5
+ class Bitcoin::Script
6
+
7
+ OP_0 = 0
8
+ OP_FALSE = 0
9
+ OP_1 = 81
10
+ OP_TRUE = 81
11
+ OP_2 = 0x52
12
+ OP_3 = 0x53
13
+ OP_4 = 0x54
14
+ OP_5 = 0x55
15
+ OP_6 = 0x56
16
+ OP_7 = 0x57
17
+ OP_8 = 0x58
18
+ OP_9 = 0x59
19
+ OP_10 = 0x5a
20
+ OP_11 = 0x5b
21
+ OP_12 = 0x5c
22
+ OP_13 = 0x5d
23
+ OP_14 = 0x5e
24
+ OP_15 = 0x5f
25
+ OP_16 = 0x60
26
+
27
+ OP_PUSHDATA0 = 0
28
+ OP_PUSHDATA1 = 76
29
+ OP_PUSHDATA2 = 77
30
+ OP_PUSHDATA4 = 78
31
+ OP_PUSHDATA_INVALID = 238 # 0xEE
32
+ OP_NOP = 97
33
+ OP_DUP = 118
34
+ OP_HASH160 = 169
35
+ OP_EQUAL = 135
36
+ OP_VERIFY = 105
37
+ OP_EQUALVERIFY = 136
38
+ OP_CHECKSIG = 172
39
+ OP_CHECKSIGVERIFY = 173
40
+ OP_CHECKMULTISIG = 174
41
+ OP_CHECKMULTISIGVERIFY = 175
42
+ OP_TOALTSTACK = 107
43
+ OP_FROMALTSTACK = 108
44
+ OP_TUCK = 125
45
+ OP_SWAP = 124
46
+ OP_BOOLAND = 154
47
+ OP_ADD = 147
48
+ OP_SUB = 148
49
+ OP_GREATERTHANOREQUAL = 162
50
+ OP_DROP = 117
51
+ OP_HASH256 = 170
52
+ OP_SHA256 = 168
53
+ OP_SHA1 = 167
54
+ OP_RIPEMD160 = 166
55
+ OP_NOP1 = 176
56
+ OP_NOP2 = 177
57
+ OP_NOP3 = 178
58
+ OP_NOP4 = 179
59
+ OP_NOP5 = 180
60
+ OP_NOP6 = 181
61
+ OP_NOP7 = 182
62
+ OP_NOP8 = 183
63
+ OP_NOP9 = 184
64
+ OP_NOP10 = 185
65
+ OP_CODESEPARATOR = 171
66
+ OP_MIN = 163
67
+ OP_MAX = 164
68
+ OP_2OVER = 112
69
+ OP_2ROT = 113
70
+ OP_2SWAP = 114
71
+ OP_IFDUP = 115
72
+ OP_DEPTH = 116
73
+ OP_1NEGATE = 79
74
+ OP_WITHIN = 165
75
+ OP_NUMEQUAL = 156
76
+ OP_NUMEQUALVERIFY = 157
77
+ OP_LESSTHAN = 159
78
+ OP_LESSTHANOREQUAL = 161
79
+ OP_GREATERTHAN = 160
80
+ OP_NOT = 145
81
+ OP_0NOTEQUAL = 146
82
+ OP_ABS = 144
83
+ OP_1ADD = 139
84
+ OP_1SUB = 140
85
+ OP_NEGATE = 143
86
+ OP_BOOLOR = 155
87
+ OP_NUMNOTEQUAL = 158
88
+ OP_RETURN = 106
89
+ OP_OVER = 120
90
+ OP_IF = 99
91
+ OP_NOTIF = 100
92
+ OP_ELSE = 103
93
+ OP_ENDIF = 104
94
+ OP_PICK = 121
95
+ OP_SIZE = 130
96
+ OP_VER = 98
97
+ OP_ROLL = 122
98
+ OP_ROT = 123
99
+ OP_2DROP = 109
100
+ OP_2DUP = 110
101
+ OP_3DUP = 111
102
+ OP_NIP = 119
103
+
104
+ OP_CAT = 126
105
+ OP_SUBSTR = 127
106
+ OP_LEFT = 128
107
+ OP_RIGHT = 129
108
+ OP_INVERT = 131
109
+ OP_AND = 132
110
+ OP_OR = 133
111
+ OP_XOR = 134
112
+ OP_2MUL = 141
113
+ OP_2DIV = 142
114
+ OP_MUL = 149
115
+ OP_DIV = 150
116
+ OP_MOD = 151
117
+ OP_LSHIFT = 152
118
+ OP_RSHIFT = 153
119
+
120
+ OP_INVALIDOPCODE = 0xff
121
+
122
+ OPCODES = Hash[*constants.grep(/^OP_/).map{|i| [const_get(i), i.to_s] }.flatten]
123
+ OPCODES[0] = "0"
124
+ OPCODES[81] = "1"
125
+
126
+ OPCODES_ALIAS = {
127
+ "OP_TRUE" => OP_1,
128
+ "OP_FALSE" => OP_0,
129
+ "OP_EVAL" => OP_NOP1,
130
+ "OP_CHECKHASHVERIFY" => OP_NOP2,
131
+ }
132
+
133
+ DISABLED_OPCODES = [
134
+ OP_CAT, OP_SUBSTR, OP_LEFT, OP_RIGHT, OP_INVERT,
135
+ OP_AND, OP_OR, OP_XOR, OP_2MUL, OP_2DIV, OP_MUL,
136
+ OP_DIV, OP_MOD, OP_LSHIFT, OP_RSHIFT
137
+ ]
138
+
139
+ OP_2_16 = (82..96).to_a
140
+
141
+
142
+ OPCODES_PARSE_BINARY = {}
143
+ OPCODES.each{|k,v| OPCODES_PARSE_BINARY[k] = v }
144
+ OP_2_16.each{|i| OPCODES_PARSE_BINARY[i] = (OP_2_16.index(i)+2).to_s }
145
+
146
+ OPCODES_PARSE_STRING = {}
147
+ OPCODES.each{|k,v| OPCODES_PARSE_STRING[v] = k }
148
+ OPCODES_ALIAS.each{|k,v| OPCODES_PARSE_STRING[k] = v }
149
+ 2.upto(16).each{|i| OPCODES_PARSE_STRING["OP_#{i}"] = OP_2_16[i-2] }
150
+ 2.upto(16).each{|i| OPCODES_PARSE_STRING["#{i}" ] = OP_2_16[i-2] }
151
+ [1,2,4].each{|i| OPCODES_PARSE_STRING.delete("OP_PUSHDATA#{i}") }
152
+
153
+ SIGHASH_TYPE = {
154
+ all: 1,
155
+ none: 2,
156
+ single: 3,
157
+ forkid: 64,
158
+ anyonecanpay: 128
159
+ }.freeze
160
+
161
+ attr_reader :raw, :chunks, :debug, :stack
162
+
163
+ # create a new script. +bytes+ is typically input_script + output_script
164
+ def initialize(input_script, previous_output_script=nil)
165
+ @raw_byte_sizes = [input_script.bytesize, previous_output_script ? previous_output_script.bytesize : 0]
166
+ @input_script, @previous_output_script = input_script, previous_output_script
167
+
168
+ @raw = if @previous_output_script
169
+ @input_script + [ Bitcoin::Script::OP_CODESEPARATOR ].pack("C") + @previous_output_script
170
+ else
171
+ @input_script
172
+ end
173
+
174
+ @chunks = parse(@input_script)
175
+
176
+ if previous_output_script
177
+ @script_codeseparator_index = @chunks.size
178
+ @chunks << Bitcoin::Script::OP_CODESEPARATOR
179
+ @chunks += parse(@previous_output_script)
180
+ end
181
+
182
+ @stack, @stack_alt, @exec_stack = [], [], []
183
+ @last_codeseparator_index = 0
184
+ @do_exec = true
185
+ end
186
+
187
+ class ::String
188
+ attr_accessor :bitcoin_pushdata
189
+ attr_accessor :bitcoin_pushdata_length
190
+ end
191
+
192
+ # parse raw script
193
+ def parse(bytes, offset=0)
194
+ program = bytes.unpack("C*")
195
+ chunks = []
196
+ until program.empty?
197
+ opcode = program.shift
198
+
199
+ if (opcode > 0) && (opcode < OP_PUSHDATA1)
200
+ len, tmp = opcode, program[0]
201
+ chunks << program.shift(len).pack("C*")
202
+
203
+ # 0x16 = 22 due to OP_2_16 from_string parsing
204
+ if len == 1 && tmp && tmp <= 22
205
+ chunks.last.bitcoin_pushdata = OP_PUSHDATA0
206
+ chunks.last.bitcoin_pushdata_length = len
207
+ else
208
+ raise "invalid OP_PUSHDATA0" if len != chunks.last.bytesize
209
+ end
210
+ elsif (opcode == OP_PUSHDATA1)
211
+ len = program.shift(1)[0]
212
+ chunks << program.shift(len).pack("C*")
213
+
214
+ unless len > OP_PUSHDATA1 && len <= 0xff
215
+ chunks.last.bitcoin_pushdata = OP_PUSHDATA1
216
+ chunks.last.bitcoin_pushdata_length = len
217
+ else
218
+ raise "invalid OP_PUSHDATA1" if len != chunks.last.bytesize
219
+ end
220
+ elsif (opcode == OP_PUSHDATA2)
221
+ len = program.shift(2).pack("C*").unpack("v")[0]
222
+ chunks << program.shift(len).pack("C*")
223
+
224
+ unless len > 0xff && len <= 0xffff
225
+ chunks.last.bitcoin_pushdata = OP_PUSHDATA2
226
+ chunks.last.bitcoin_pushdata_length = len
227
+ else
228
+ raise "invalid OP_PUSHDATA2" if len != chunks.last.bytesize
229
+ end
230
+ elsif (opcode == OP_PUSHDATA4)
231
+ len = program.shift(4).pack("C*").unpack("V")[0]
232
+ chunks << program.shift(len).pack("C*")
233
+
234
+ unless len > 0xffff # && len <= 0xffffffff
235
+ chunks.last.bitcoin_pushdata = OP_PUSHDATA4
236
+ chunks.last.bitcoin_pushdata_length = len
237
+ else
238
+ raise "invalid OP_PUSHDATA4" if len != chunks.last.bytesize
239
+ end
240
+ else
241
+ chunks << opcode
242
+ end
243
+ end
244
+ chunks
245
+ rescue => ex
246
+ # bail out! #run returns false but serialization roundtrips still create the right payload.
247
+ chunks.pop if ex.message.include?("invalid OP_PUSHDATA")
248
+ @parse_invalid = true
249
+ c = bytes.unpack("C*").pack("C*")
250
+ c.bitcoin_pushdata = OP_PUSHDATA_INVALID
251
+ c.bitcoin_pushdata_length = c.bytesize
252
+ chunks << c
253
+ end
254
+
255
+ # string representation of the script
256
+ def to_string(chunks=nil)
257
+ string = ""
258
+ (chunks || @chunks).each.with_index{|i,idx|
259
+ string << " " unless idx == 0
260
+ string << case i
261
+ when Fixnum
262
+ if opcode = OPCODES_PARSE_BINARY[i]
263
+ opcode
264
+ else
265
+ "(opcode-#{i})"
266
+ end
267
+ when String
268
+ if i.bitcoin_pushdata
269
+ "#{i.bitcoin_pushdata}:#{i.bitcoin_pushdata_length}:".force_encoding('binary') + i.unpack("H*")[0]
270
+ else
271
+ i.unpack("H*")[0]
272
+ end
273
+ end
274
+ }
275
+ string
276
+ end
277
+
278
+ def to_binary(chunks=nil)
279
+ (chunks || @chunks).map{|chunk|
280
+ case chunk
281
+ when Fixnum; [chunk].pack("C*")
282
+ when String; self.class.pack_pushdata(chunk)
283
+ end
284
+ }.join
285
+ end
286
+ alias :to_payload :to_binary
287
+
288
+ def to_binary_without_signatures(drop_signatures, chunks=nil)
289
+ buf = []
290
+ (chunks || @chunks).each.with_index{|chunk,idx|
291
+ if chunk == OP_CODESEPARATOR and idx <= @last_codeseparator_index
292
+ buf.clear
293
+ elsif chunk == OP_CODESEPARATOR
294
+ if idx == @script_codeseparator_index
295
+ break
296
+ else
297
+ # skip
298
+ end
299
+ elsif drop_signatures.none?{|e| e == chunk }
300
+ buf << chunk
301
+ end
302
+ }
303
+ to_binary(buf)
304
+ end
305
+
306
+ # Returns a script that deleted the script before the index specified by separator_index.
307
+ def subscript_codeseparator(separator_index)
308
+ buf = []
309
+ process_separator_index = 0
310
+ (chunks || @chunks).each{|chunk|
311
+ buf << chunk if process_separator_index == separator_index
312
+ process_separator_index += 1 if chunk == OP_CODESEPARATOR and process_separator_index < separator_index
313
+ }
314
+ to_binary(buf)
315
+ end
316
+
317
+ # Adds opcode (OP_0, OP_1, ... OP_CHECKSIG etc.)
318
+ # Returns self.
319
+ def append_opcode(opcode)
320
+ raise "Opcode should be a Fixnum" if !opcode.is_a?(Fixnum)
321
+ if opcode >= OP_0 && opcode <= 0xff
322
+ @chunks << opcode
323
+ else
324
+ raise "Opcode should be within [0x00, 0xff]"
325
+ end
326
+ self
327
+ end
328
+
329
+ # Adds the opcode corresponding to the given number. Returns self.
330
+ def append_number(number)
331
+ opcode =
332
+ case number
333
+ when -1 then OP_1NEGATE
334
+ when 0 then OP_0
335
+ when 1 then OP_1
336
+ when 2..16 then OP_2 + (16 - number)
337
+ end
338
+ raise "No opcode for number #{number}" if opcode.nil?
339
+ append_opcode(opcode)
340
+ end
341
+
342
+ # Adds binary string as pushdata. Pushdata will be encoded in the most compact form
343
+ # (unless the string contains internal info about serialization that's added by Script class)
344
+ # Returns self.
345
+ def append_pushdata(pushdata_string)
346
+ raise "Pushdata should be a string" if !pushdata_string.is_a?(String)
347
+ @chunks << pushdata_string
348
+ self
349
+ end
350
+
351
+ def self.pack_pushdata(data)
352
+ size = data.bytesize
353
+
354
+ if data.bitcoin_pushdata
355
+ size = data.bitcoin_pushdata_length
356
+ pack_pushdata_align(data.bitcoin_pushdata, size, data)
357
+ else
358
+ head = if size < OP_PUSHDATA1
359
+ [size].pack("C")
360
+ elsif size <= 0xff
361
+ [OP_PUSHDATA1, size].pack("CC")
362
+ elsif size <= 0xffff
363
+ [OP_PUSHDATA2, size].pack("Cv")
364
+ #elsif size <= 0xffffffff
365
+ else
366
+ [OP_PUSHDATA4, size].pack("CV")
367
+ end
368
+ head + data
369
+ end
370
+ end
371
+
372
+ def self.pack_pushdata_align(pushdata, len, data)
373
+ case pushdata
374
+ when OP_PUSHDATA1
375
+ [OP_PUSHDATA1, len].pack("CC") + data
376
+ when OP_PUSHDATA2
377
+ [OP_PUSHDATA2, len].pack("Cv") + data
378
+ when OP_PUSHDATA4
379
+ [OP_PUSHDATA4, len].pack("CV") + data
380
+ when OP_PUSHDATA_INVALID
381
+ data
382
+ else # OP_PUSHDATA0
383
+ [len].pack("C") + data
384
+ end
385
+ end
386
+
387
+ # script object of a string representation
388
+ def self.from_string(input_script, previous_output_script=nil)
389
+ if previous_output_script
390
+ new(binary_from_string(input_script), binary_from_string(previous_output_script))
391
+ else
392
+ new(binary_from_string(input_script))
393
+ end
394
+ end
395
+
396
+ class ScriptOpcodeError < StandardError; end
397
+
398
+ # raw script binary of a string representation
399
+ def self.binary_from_string(script_string)
400
+ buf = ""
401
+ script_string.split(" ").each{|i|
402
+ i = if opcode = OPCODES_PARSE_STRING[i]
403
+ opcode
404
+ else
405
+ case i
406
+ when /OP_PUSHDATA/ # skip
407
+ when /OP_(.+)$/; raise ScriptOpcodeError, "#{i} not defined!"
408
+ when /\(opcode\-(\d+)\)/; $1.to_i
409
+ when "(opcode"; # skip # fix invalid opcode parsing
410
+ when /^(\d+)\)/; $1.to_i # fix invalid opcode parsing
411
+ when /(\d+):(\d+):(.+)?/
412
+ pushdata, len, data = $1.to_i, $2.to_i, $3
413
+ pack_pushdata_align(pushdata, len, [data].pack("H*"))
414
+ else
415
+ data = [i].pack("H*")
416
+ pack_pushdata(data)
417
+ end
418
+ end
419
+
420
+ buf << if i.is_a?(Fixnum)
421
+ i < 256 ? [i].pack("C") : [OpenSSL::BN.new(i.to_s,10).to_hex].pack("H*")
422
+ else
423
+ i
424
+ end if i
425
+ }
426
+ buf
427
+ end
428
+
429
+ def invalid?
430
+ @script_invalid ||= false
431
+ end
432
+
433
+ # run the script. +check_callback+ is called for OP_CHECKSIG operations
434
+ def run(block_timestamp=Time.now.to_i, opts={}, &check_callback)
435
+ return false if @parse_invalid
436
+
437
+ #p [to_string, block_timestamp, is_p2sh?]
438
+ @script_invalid = true if @raw_byte_sizes.any?{|size| size > 10_000 }
439
+ @last_codeseparator_index = 0
440
+
441
+ if block_timestamp >= 1333238400 # Pay to Script Hash (BIP 0016)
442
+ return pay_to_script_hash(block_timestamp, opts, check_callback) if is_p2sh?
443
+ end
444
+
445
+ @debug = []
446
+ @chunks.each.with_index{|chunk,idx|
447
+ break if invalid?
448
+ @chunk_last_index = idx
449
+
450
+ @debug << @stack.map{|i| i.unpack("H*") rescue i}
451
+ @do_exec = @exec_stack.count(false) == 0 ? true : false
452
+ #p [@stack, @do_exec]
453
+
454
+ case chunk
455
+ when Fixnum
456
+ if DISABLED_OPCODES.include?(chunk)
457
+ @script_invalid = true
458
+ @debug << "DISABLED_#{OPCODES[chunk]}"
459
+ break
460
+ end
461
+
462
+ next @debug.pop unless (@do_exec || (OP_IF <= chunk && chunk <= OP_ENDIF))
463
+
464
+ case chunk
465
+ when *OPCODES_METHOD.keys
466
+ m = method( n=OPCODES_METHOD[chunk] )
467
+ @debug << n.to_s.upcase
468
+ # invoke opcode method
469
+ case m.arity
470
+ when 0
471
+ m.call
472
+ when 1
473
+ m.call(check_callback)
474
+ when -2 # One fixed parameter, one optional
475
+ m.call(check_callback, opts)
476
+ else
477
+ puts "Bitcoin::Script: opcode #{name} method parameters invalid"
478
+ end
479
+ when *OP_2_16
480
+ @stack << OP_2_16.index(chunk) + 2
481
+ @debug << "OP_#{chunk-80}"
482
+ else
483
+ name = OPCODES[chunk] || chunk
484
+ puts "Bitcoin::Script: opcode #{name} unkown or not implemented\n#{to_string.inspect}"
485
+ raise "opcode #{name} unkown or not implemented"
486
+ end
487
+ when String
488
+ if @do_exec
489
+ @debug << "PUSH DATA #{chunk.unpack("H*")[0]}"
490
+ @stack << chunk
491
+ else
492
+ @debug.pop
493
+ end
494
+ end
495
+ }
496
+ @debug << @stack.map{|i| i.unpack("H*") rescue i } #if @do_exec
497
+
498
+ if @script_invalid
499
+ @stack << 0
500
+ @debug << "INVALID TRANSACTION"
501
+ end
502
+
503
+ @debug << "RESULT"
504
+ return false if @stack.empty?
505
+ return false if cast_to_bool(@stack.pop) == false
506
+ true
507
+ end
508
+
509
+ def invalid
510
+ @script_invalid = true; nil
511
+ end
512
+
513
+ def self.drop_signatures(script_pubkey, drop_signatures)
514
+ script = new(script_pubkey).to_string.split(" ").delete_if{|c| drop_signatures.include?(c) }.join(" ")
515
+ script_pubkey = binary_from_string(script)
516
+ end
517
+
518
+ # pay_to_script_hash: https://en.bitcoin.it/wiki/BIP_0016
519
+ #
520
+ # <sig> {<pub> OP_CHECKSIG} | OP_HASH160 <script_hash> OP_EQUAL
521
+ def pay_to_script_hash(block_timestamp, opts, check_callback)
522
+ return false if @chunks.size < 4
523
+ *rest, script, _, script_hash, _ = @chunks
524
+ script = rest.pop if script == OP_CODESEPARATOR
525
+ script, script_hash = cast_to_string(script), cast_to_string(script_hash)
526
+
527
+ return false unless Bitcoin.hash160(script.unpack("H*")[0]) == script_hash.unpack("H*")[0]
528
+ return true if check_callback == :check
529
+
530
+ script = self.class.new(to_binary(rest) + script).inner_p2sh!(script)
531
+ result = script.run(block_timestamp, opts, &check_callback)
532
+ @debug = script.debug
533
+ @stack = script.stack # Set the execution stack to match the redeem script, so checks on stack contents at end of script execution validate correctly
534
+ result
535
+ end
536
+
537
+ def inner_p2sh!(script=nil); @inner_p2sh = true; @inner_script_code = script; self; end
538
+ def inner_p2sh?; @inner_p2sh; end
539
+
540
+ # get the inner p2sh script
541
+ def inner_p2sh_script
542
+ return nil if @chunks.size < 4
543
+ *rest, script, _, script_hash, _ = @chunks
544
+ script = rest.pop if script == OP_CODESEPARATOR
545
+ script, script_hash = cast_to_string(script), cast_to_string(script_hash)
546
+
547
+ return nil unless Bitcoin.hash160(script.unpack("H*")[0]) == script_hash.unpack("H*")[0]
548
+ script
549
+ end
550
+
551
+ # is this a :script_hash (pay-to-script-hash/p2sh) script?
552
+ def is_pay_to_script_hash?
553
+ return false if @inner_p2sh
554
+ if @previous_output_script
555
+ chunks = Bitcoin::Script.new(@previous_output_script).chunks
556
+ chunks.size == 3 &&
557
+ chunks[-3] == OP_HASH160 &&
558
+ chunks[-2].is_a?(String) && chunks[-2].bytesize == 20 &&
559
+ chunks[-1] == OP_EQUAL
560
+ else
561
+ @chunks.size >= 3 &&
562
+ @chunks[-3] == OP_HASH160 &&
563
+ @chunks[-2].is_a?(String) && @chunks[-2].bytesize == 20 &&
564
+ @chunks[-1] == OP_EQUAL &&
565
+ # make sure the script_sig matches the p2sh hash from the pk_script (if there is one)
566
+ (@chunks.size > 3 ? pay_to_script_hash(nil, nil, :check) : true)
567
+ end
568
+ end
569
+ alias :is_p2sh? :is_pay_to_script_hash?
570
+
571
+ # check if script is in one of the recognized standard formats
572
+ def is_standard?
573
+ is_pubkey? || is_hash160? || is_multisig? || is_p2sh? || is_op_return? || is_witness_v0_keyhash? || is_witness_v0_scripthash?
574
+ end
575
+
576
+ # is this a pubkey script
577
+ def is_pubkey?
578
+ return false if @chunks.size != 2
579
+ (@chunks[1] == OP_CHECKSIG) && @chunks[0] && (@chunks[0].is_a?(String)) && @chunks[0] != OP_RETURN
580
+ end
581
+ alias :is_send_to_ip? :is_pubkey?
582
+
583
+ # is this a hash160 (address) script
584
+ def is_hash160?
585
+ return false if @chunks.size != 5
586
+ (@chunks[0..1] + @chunks[-2..-1]) ==
587
+ [OP_DUP, OP_HASH160, OP_EQUALVERIFY, OP_CHECKSIG] &&
588
+ @chunks[2].is_a?(String) && @chunks[2].bytesize == 20
589
+ end
590
+
591
+ # is this a multisig script
592
+ def is_multisig?
593
+ return false if @chunks.size < 4 || !@chunks[-2].is_a?(Fixnum)
594
+ @chunks[-1] == OP_CHECKMULTISIG and get_multisig_pubkeys.all?{|c| c.is_a?(String) }
595
+ end
596
+
597
+ # is this an op_return script
598
+ def is_op_return?
599
+ @chunks[0] == OP_RETURN && @chunks.size <= 2
600
+ end
601
+
602
+ # is this a witness script(witness_v0_keyhash or witness_v0_scripthash)
603
+ def is_witness?
604
+ is_witness_v0_keyhash? || is_witness_v0_scripthash?
605
+ end
606
+
607
+ # is this a witness pubkey script
608
+ def is_witness_v0_keyhash?
609
+ @chunks.length == 2 &&@chunks[0] == 0 && @chunks[1].is_a?(String) && @chunks[1].bytesize == 20
610
+ end
611
+
612
+ # is this a witness script hash
613
+ def is_witness_v0_scripthash?
614
+ @chunks.length == 2 &&@chunks[0] == 0 && @chunks[1].is_a?(String) && @chunks[1].bytesize == 32
615
+ end
616
+
617
+ # Verify the script is only pushing data onto the stack
618
+ def is_push_only?(script_data=nil)
619
+ check_pushes(push_only=true, canonical_only=false, (script_data||@input_script))
620
+ end
621
+
622
+ # Make sure opcodes used to push data match their intended length ranges
623
+ def pushes_are_canonical?(script_data=nil)
624
+ check_pushes(push_only=false, canonical_only=true, (script_data||@raw))
625
+ end
626
+
627
+ def check_pushes(push_only=true, canonical_only=false, buf)
628
+ program = buf.unpack("C*")
629
+ until program.empty?
630
+ opcode = program.shift
631
+ if opcode > OP_16
632
+ return false if push_only
633
+ next
634
+ end
635
+ if opcode < OP_PUSHDATA1 && opcode > OP_0
636
+ # Could have used an OP_n code, rather than a 1-byte push.
637
+ return false if canonical_only && opcode == 1 && program[0] <= 16
638
+ program.shift(opcode)
639
+ end
640
+ if opcode == OP_PUSHDATA1
641
+ len = program.shift(1)[0]
642
+ # Could have used a normal n-byte push, rather than OP_PUSHDATA1.
643
+ return false if canonical_only && len < OP_PUSHDATA1
644
+ program.shift(len)
645
+ end
646
+ if opcode == OP_PUSHDATA2
647
+ len = program.shift(2).pack("C*").unpack("v")[0]
648
+ # Could have used an OP_PUSHDATA1.
649
+ return false if canonical_only && len <= 0xff
650
+ program.shift(len)
651
+ end
652
+ if opcode == OP_PUSHDATA4
653
+ len = program.shift(4).pack("C*").unpack("V")[0]
654
+ # Could have used an OP_PUSHDATA2.
655
+ return false if canonical_only && len <= 0xffff
656
+ program.shift(len)
657
+ end
658
+ end
659
+ true
660
+ rescue
661
+ # catch parsing errors
662
+ false
663
+ end
664
+
665
+ # get type of this tx
666
+ def type
667
+ if is_hash160?; :hash160
668
+ elsif is_pubkey?; :pubkey
669
+ elsif is_multisig?; :multisig
670
+ elsif is_p2sh?; :p2sh
671
+ elsif is_op_return?; :op_return
672
+ elsif is_witness_v0_keyhash?; :witness_v0_keyhash
673
+ elsif is_witness_v0_scripthash?;:witness_v0_scripthash
674
+ else; :unknown
675
+ end
676
+ end
677
+
678
+ # get the public key for this pubkey script
679
+ def get_pubkey
680
+ return @chunks[0].unpack("H*")[0] if @chunks.size == 1
681
+ is_pubkey? ? @chunks[0].unpack("H*")[0] : nil
682
+ end
683
+
684
+ # get the pubkey address for this pubkey script
685
+ def get_pubkey_address
686
+ Bitcoin.pubkey_to_address(get_pubkey)
687
+ end
688
+
689
+ # get the hash160 for this hash160 or pubkey script
690
+ def get_hash160
691
+ return @chunks[2..-3][0].unpack("H*")[0] if is_hash160?
692
+ return @chunks[-2].unpack("H*")[0] if is_p2sh?
693
+ return Bitcoin.hash160(get_pubkey) if is_pubkey?
694
+ return @chunks[1].unpack("H*")[0] if is_witness_v0_keyhash?
695
+ return @chunks[1].unpack("H*")[0] if is_witness_v0_scripthash?
696
+ end
697
+
698
+ # get the hash160 address for this hash160 script
699
+ def get_hash160_address
700
+ Bitcoin.hash160_to_address(get_hash160)
701
+ end
702
+
703
+ # get the public keys for this multisig script
704
+ def get_multisig_pubkeys
705
+ 1.upto(@chunks[-2] - 80).map{|i| @chunks[i] }
706
+ end
707
+
708
+ # get the pubkey addresses for this multisig script
709
+ def get_multisig_addresses
710
+ get_multisig_pubkeys.map{|pub|
711
+ begin
712
+ Bitcoin::Key.new(nil, pub.unpack("H*")[0]).addr
713
+ rescue OpenSSL::PKey::ECError, OpenSSL::PKey::EC::Point::Error
714
+ end
715
+ }
716
+ end
717
+
718
+ def get_p2sh_address
719
+ Bitcoin.hash160_to_p2sh_address(get_hash160)
720
+ end
721
+
722
+ # get the data possibly included in an OP_RETURN script
723
+ def get_op_return_data
724
+ return nil unless is_op_return?
725
+ cast_to_string(@chunks[1]).unpack("H*")[0] if @chunks[1]
726
+ end
727
+
728
+ # get all addresses this script corresponds to (if possible)
729
+ def get_addresses
730
+ return [get_pubkey_address] if is_pubkey?
731
+ return [get_hash160_address] if is_hash160?
732
+ return get_multisig_addresses if is_multisig?
733
+ return [get_p2sh_address] if is_p2sh?
734
+ []
735
+ end
736
+
737
+ # get single address, or first for multisig script
738
+ def get_address
739
+ addrs = get_addresses
740
+ addrs.is_a?(Array) ? addrs[0] : addrs
741
+ end
742
+
743
+ # generate pubkey tx script for given +pubkey+. returns a raw binary script of the form:
744
+ # <pubkey> OP_CHECKSIG
745
+ def self.to_pubkey_script(pubkey)
746
+ pack_pushdata([pubkey].pack("H*")) + [ OP_CHECKSIG ].pack("C")
747
+ end
748
+
749
+ # generate hash160 tx for given +address+. returns a raw binary script of the form:
750
+ # OP_DUP OP_HASH160 <hash160> OP_EQUALVERIFY OP_CHECKSIG
751
+ def self.to_hash160_script(hash160)
752
+ return nil unless hash160
753
+ # DUP HASH160 length hash160 EQUALVERIFY CHECKSIG
754
+ [ ["76", "a9", "14", hash160, "88", "ac"].join ].pack("H*")
755
+ end
756
+
757
+ # generate p2sh output script for given +p2sh+ hash160. returns a raw binary script of the form:
758
+ # OP_HASH160 <p2sh> OP_EQUAL
759
+ def self.to_p2sh_script(p2sh)
760
+ return nil unless p2sh
761
+ # HASH160 length hash EQUAL
762
+ [ ["a9", "14", p2sh, "87"].join ].pack("H*")
763
+ end
764
+
765
+ # generate p2wpkh tx for given +address+. returns a raw binary script of the form:
766
+ # 0 <hash160>
767
+ def self.to_witness_hash160_script(hash160)
768
+ return nil unless hash160
769
+ # witness ver length hash160
770
+ [ ["00", "14", hash160].join ].pack("H*")
771
+ end
772
+
773
+ # generate p2wsh output script for given +p2sh+ sha256. returns a raw binary script of the form:
774
+ # 0 <p2sh>
775
+ def self.to_witness_p2sh_script(p2sh)
776
+ return nil unless p2sh
777
+ # witness ver length sha256
778
+ [ [ "00", "20", p2sh].join].pack("H*")
779
+ end
780
+
781
+ # generate hash160 or p2sh output script, depending on the type of the given +address+.
782
+ # see #to_hash160_script and #to_p2sh_script.
783
+ def self.to_address_script(address)
784
+ hash160 = Bitcoin.hash160_from_address(address)
785
+ case Bitcoin.address_type(address)
786
+ when :hash160; to_hash160_script(hash160)
787
+ when :p2sh; to_p2sh_script(hash160)
788
+ end
789
+ end
790
+
791
+ # generate multisig output script for given +pubkeys+, expecting +m+ signatures.
792
+ # returns a raw binary script of the form:
793
+ # <m> <pubkey> [<pubkey> ...] <n_pubkeys> OP_CHECKMULTISIG
794
+ def self.to_multisig_script(m, *pubkeys)
795
+ raise "invalid m-of-n number" unless [m, pubkeys.size].all?{|i| (0..20).include?(i) }
796
+ raise "invalid m-of-n number" if pubkeys.size < m
797
+ pubs = pubkeys.map{|pk| pack_pushdata([pk].pack("H*")) }
798
+
799
+ m = m > 16 ? pack_pushdata([m].pack("C")) : [80 + m.to_i].pack("C")
800
+ n = pubkeys.size > 16 ? pack_pushdata([pubkeys.size].pack("C")) : [80 + pubs.size].pack("C")
801
+
802
+ [ m, *pubs, n, [OP_CHECKMULTISIG].pack("C")].join
803
+ end
804
+
805
+ # generate OP_RETURN output script with given data. returns a raw binary script of the form:
806
+ # OP_RETURN <data>
807
+ def self.to_op_return_script(data = nil)
808
+ buf = [ OP_RETURN ].pack("C")
809
+ return buf unless data
810
+ return buf + pack_pushdata( [data].pack("H*") )
811
+ end
812
+
813
+ # generate input script sig spending a pubkey output with given +signature+ and +pubkey+.
814
+ # returns a raw binary script sig of the form:
815
+ # <signature> [<pubkey>]
816
+ def self.to_pubkey_script_sig(signature, pubkey, hash_type = SIGHASH_TYPE[:all])
817
+ buf = pack_pushdata(signature + [hash_type].pack("C"))
818
+ return buf unless pubkey
819
+
820
+ expected_size = case pubkey[0]
821
+ when "\x04"; 65
822
+ when "\x02", "\x03"; 33
823
+ end
824
+
825
+ raise "pubkey is not in binary form" if !expected_size || pubkey.bytesize != expected_size
826
+
827
+ return buf + pack_pushdata(pubkey)
828
+ end
829
+
830
+ # generate p2sh multisig output script for given +args+.
831
+ # returns the p2sh output script, and the redeem script needed to spend it.
832
+ # see #to_multisig_script for the redeem script, and #to_p2sh_script for the p2sh script.
833
+ def self.to_p2sh_multisig_script(*args)
834
+ redeem_script = to_multisig_script(*args)
835
+ p2sh_script = to_p2sh_script(Bitcoin.hash160(redeem_script.hth))
836
+ return p2sh_script, redeem_script
837
+ end
838
+
839
+ # alias for #to_pubkey_script_sig
840
+ def self.to_signature_pubkey_script(*a)
841
+ to_pubkey_script_sig(*a)
842
+ end
843
+
844
+ # generate input script sig spending a multisig output script.
845
+ # returns a raw binary script sig of the form:
846
+ # OP_0 <sig> [<sig> ...]
847
+ def self.to_multisig_script_sig(*sigs)
848
+ hash_type = sigs.last.is_a?(Numeric) ? sigs.pop : SIGHASH_TYPE[:all]
849
+ partial_script = [OP_0].pack("C*")
850
+ sigs.reverse_each{ |sig| partial_script = add_sig_to_multisig_script_sig(sig, partial_script, hash_type) }
851
+ partial_script
852
+ end
853
+
854
+ # take a multisig script sig (or p2sh multisig script sig) and add
855
+ # another signature to it after the OP_0. Used to sign a tx by
856
+ # multiple parties. Signatures must be in the same order as the
857
+ # pubkeys in the output script being redeemed.
858
+ def self.add_sig_to_multisig_script_sig(sig, script_sig, hash_type = SIGHASH_TYPE[:all])
859
+ signature = sig + [hash_type].pack("C*")
860
+ offset = script_sig.empty? ? 0 : 1
861
+ script_sig.insert(offset, pack_pushdata(signature))
862
+ end
863
+
864
+ # generate input script sig spending a p2sh-multisig output script.
865
+ # returns a raw binary script sig of the form:
866
+ # OP_0 <sig> [<sig> ...] <redeem_script>
867
+ def self.to_p2sh_multisig_script_sig(redeem_script, *sigs)
868
+ to_multisig_script_sig(*sigs.flatten) + pack_pushdata(redeem_script)
869
+ end
870
+
871
+ # Sort signatures in the given +script_sig+ according to the order of pubkeys in
872
+ # the redeem script. Also needs the +sig_hash+ to match signatures to pubkeys.
873
+ def self.sort_p2sh_multisig_signatures script_sig, sig_hash
874
+ script = new(script_sig)
875
+ redeem_script = new(script.chunks[-1])
876
+ pubkeys = redeem_script.get_multisig_pubkeys
877
+
878
+ # find the pubkey for each signature by trying to verify it
879
+ sigs = Hash[script.chunks[1...-1].map.with_index do |sig, idx|
880
+ pubkey = pubkeys.map {|key|
881
+ Bitcoin::Key.new(nil, key.hth).verify(sig_hash, sig) ? key : nil }.compact.first
882
+ raise "Key for signature ##{idx} not found in redeem script!" unless pubkey
883
+ [pubkey, sig]
884
+ end]
885
+
886
+ [OP_0].pack("C*") + pubkeys.map {|k| sigs[k] ? pack_pushdata(sigs[k]) : nil }.join +
887
+ pack_pushdata(redeem_script.raw)
888
+ end
889
+
890
+ def get_signatures_required
891
+ return false unless is_multisig?
892
+ @chunks[0] - 80
893
+ end
894
+
895
+ def get_keys_provided
896
+ return false unless is_multisig?
897
+ @chunks[-2] - 80
898
+ end
899
+
900
+ def codeseparator_count
901
+ @chunks.select{|c|c == Bitcoin::Script::OP_CODESEPARATOR}.length
902
+ end
903
+
904
+ # This matches CScript::GetSigOpCount(bool fAccurate)
905
+ # Note: this does not cover P2SH script which is to be unserialized
906
+ # and checked explicitly when validating blocks.
907
+ def sigops_count_accurate(is_accurate)
908
+ count = 0
909
+ last_opcode = nil
910
+ @chunks.each do |chunk| # pushdate or opcode
911
+ if chunk == OP_CHECKSIG || chunk == OP_CHECKSIGVERIFY
912
+ count += 1
913
+ elsif chunk == OP_CHECKMULTISIG || chunk == OP_CHECKMULTISIGVERIFY
914
+ # Accurate mode counts exact number of pubkeys required (not signatures, but pubkeys!). Only used in P2SH scripts.
915
+ # Inaccurate mode counts every multisig as 20 signatures.
916
+ if is_accurate && last_opcode && last_opcode.is_a?(Fixnum) && last_opcode >= OP_1 && last_opcode <= OP_16
917
+ count += ::Bitcoin::Script.decode_OP_N(last_opcode)
918
+ else
919
+ count += 20
920
+ end
921
+ end
922
+ last_opcode = chunk
923
+ end
924
+ count
925
+ end
926
+
927
+ # This method applies to script_sig that is an input for p2sh output.
928
+ # Bitcoind has somewhat special way to return count for invalid input scripts:
929
+ # it returns 0 when the opcode can't be parsed or when it's over OP_16.
930
+ # Also, if the OP_{N} is used anywhere it's treated as 0-length data.
931
+ # See CScript::GetSigOpCount(const CScript& scriptSig) in bitcoind.
932
+ def sigops_count_for_p2sh
933
+ # This is a pay-to-script-hash scriptPubKey;
934
+ # get the last item that the scriptSig
935
+ # pushes onto the stack:
936
+
937
+ return 0 if @chunks.size == 0
938
+
939
+ data = nil
940
+ @chunks.each do |chunk|
941
+ case chunk
942
+ when Fixnum
943
+ data = ""
944
+ return 0 if chunk > OP_16
945
+ when String
946
+ data = chunk
947
+ end
948
+ end
949
+ return 0 if data == ""
950
+
951
+ ::Bitcoin::Script.new(data).sigops_count_accurate(true)
952
+ end
953
+
954
+ # Converts OP_{0,1,2,...,16} into 0, 1, 2, ..., 16.
955
+ # Returns nil for other opcodes.
956
+ def self.decode_OP_N(opcode)
957
+ if opcode == OP_0
958
+ return 0
959
+ end
960
+ if opcode.is_a?(Fixnum) && opcode >= OP_1 && opcode <= OP_16
961
+ return opcode - (OP_1 - 1);
962
+ else
963
+ nil
964
+ end
965
+ end
966
+
967
+
968
+
969
+
970
+ ## OPCODES
971
+
972
+ # Does nothing
973
+ def op_nop; end
974
+ def op_nop1; end
975
+ def op_nop2; end
976
+ def op_nop3; end
977
+ def op_nop4; end
978
+ def op_nop5; end
979
+ def op_nop6; end
980
+ def op_nop7; end
981
+ def op_nop8; end
982
+ def op_nop9; end
983
+ def op_nop10; end
984
+
985
+ # Duplicates the top stack item.
986
+ def op_dup
987
+ @stack << (@stack[-1].dup rescue @stack[-1])
988
+ end
989
+
990
+ # The input is hashed using SHA-256.
991
+ def op_sha256
992
+ buf = pop_string
993
+ @stack << Digest::SHA256.digest(buf)
994
+ end
995
+
996
+ # The input is hashed using SHA-1.
997
+ def op_sha1
998
+ buf = pop_string
999
+ @stack << Digest::SHA1.digest(buf)
1000
+ end
1001
+
1002
+ # The input is hashed twice: first with SHA-256 and then with RIPEMD-160.
1003
+ def op_hash160
1004
+ buf = pop_string
1005
+ @stack << Digest::RMD160.digest(Digest::SHA256.digest(buf))
1006
+ end
1007
+
1008
+ # The input is hashed using RIPEMD-160.
1009
+ def op_ripemd160
1010
+ buf = pop_string
1011
+ @stack << Digest::RMD160.digest(buf)
1012
+ end
1013
+
1014
+ # The input is hashed two times with SHA-256.
1015
+ def op_hash256
1016
+ buf = pop_string
1017
+ @stack << Digest::SHA256.digest(Digest::SHA256.digest(buf))
1018
+ end
1019
+
1020
+ # Puts the input onto the top of the alt stack. Removes it from the main stack.
1021
+ def op_toaltstack
1022
+ @stack_alt << @stack.pop
1023
+ end
1024
+
1025
+ # Puts the input onto the top of the main stack. Removes it from the alt stack.
1026
+ def op_fromaltstack
1027
+ @stack << @stack_alt.pop
1028
+ end
1029
+
1030
+ # The item at the top of the stack is copied and inserted before the second-to-top item.
1031
+ def op_tuck
1032
+ @stack[-2..-1] = [ @stack[-1], *@stack[-2..-1] ]
1033
+ end
1034
+
1035
+ # The top two items on the stack are swapped.
1036
+ def op_swap
1037
+ @stack[-2..-1] = @stack[-2..-1].reverse if @stack[-2]
1038
+ end
1039
+
1040
+ # If both a and b are not 0, the output is 1. Otherwise 0.
1041
+ def op_booland
1042
+ a, b = pop_int(2)
1043
+ @stack << (![a,b].any?{|n| n == 0 } ? 1 : 0)
1044
+ end
1045
+
1046
+ # If a or b is not 0, the output is 1. Otherwise 0.
1047
+ def op_boolor
1048
+ a, b = pop_int(2)
1049
+ @stack << ( (a != 0 || b != 0) ? 1 : 0 )
1050
+ end
1051
+
1052
+ # a is added to b.
1053
+ def op_add
1054
+ a, b = pop_int(2)
1055
+ @stack << a + b
1056
+ end
1057
+
1058
+ # b is subtracted from a.
1059
+ def op_sub
1060
+ a, b = pop_int(2)
1061
+ @stack << a - b
1062
+ end
1063
+
1064
+ # Returns 1 if a is less than b, 0 otherwise.
1065
+ def op_lessthan
1066
+ a, b = pop_int(2)
1067
+ @stack << (a < b ? 1 : 0)
1068
+ end
1069
+
1070
+ # Returns 1 if a is less than or equal to b, 0 otherwise.
1071
+ def op_lessthanorequal
1072
+ a, b = pop_int(2)
1073
+ @stack << (a <= b ? 1 : 0)
1074
+ end
1075
+
1076
+ # Returns 1 if a is greater than b, 0 otherwise.
1077
+ def op_greaterthan
1078
+ a, b = pop_int(2)
1079
+ @stack << (a > b ? 1 : 0)
1080
+ end
1081
+
1082
+ # Returns 1 if a is greater than or equal to b, 0 otherwise.
1083
+ def op_greaterthanorequal
1084
+ a, b = pop_int(2)
1085
+ @stack << (a >= b ? 1 : 0)
1086
+ end
1087
+
1088
+ # If the input is 0 or 1, it is flipped. Otherwise the output will be 0.
1089
+ def op_not
1090
+ a = pop_int
1091
+ @stack << (a == 0 ? 1 : 0)
1092
+ end
1093
+
1094
+ def op_0notequal
1095
+ a = pop_int
1096
+ @stack << (a != 0 ? 1 : 0)
1097
+ end
1098
+
1099
+ # The input is made positive.
1100
+ def op_abs
1101
+ a = pop_int
1102
+ @stack << a.abs
1103
+ end
1104
+
1105
+ # The input is divided by 2. Currently disabled.
1106
+ def op_2div
1107
+ a = pop_int
1108
+ @stack << (a >> 1)
1109
+ end
1110
+
1111
+ # The input is multiplied by 2. Currently disabled.
1112
+ def op_2mul
1113
+ a = pop_int
1114
+ @stack << (a << 1)
1115
+ end
1116
+
1117
+ # 1 is added to the input.
1118
+ def op_1add
1119
+ a = pop_int
1120
+ @stack << (a + 1)
1121
+ end
1122
+
1123
+ # 1 is subtracted from the input.
1124
+ def op_1sub
1125
+ a = pop_int
1126
+ @stack << (a - 1)
1127
+ end
1128
+
1129
+ # The sign of the input is flipped.
1130
+ def op_negate
1131
+ a = pop_int
1132
+ @stack << -a
1133
+ end
1134
+
1135
+ # Removes the top stack item.
1136
+ def op_drop
1137
+ @stack.pop
1138
+ end
1139
+
1140
+ # Returns 1 if the inputs are exactly equal, 0 otherwise.
1141
+ def op_equal
1142
+ a, b = pop_string(2)
1143
+ @stack << (a == b ? 1 : 0)
1144
+ end
1145
+
1146
+ # Marks transaction as invalid if top stack value is not true. True is removed, but false is not.
1147
+ def op_verify
1148
+ res = pop_int
1149
+ if cast_to_bool(res) == false
1150
+ @stack << res
1151
+ @script_invalid = true # raise 'transaction invalid' ?
1152
+ else
1153
+ @script_invalid = false
1154
+ end
1155
+ end
1156
+
1157
+ # Same as OP_EQUAL, but runs OP_VERIFY afterward.
1158
+ def op_equalverify
1159
+ op_equal; op_verify
1160
+ end
1161
+
1162
+ # An empty array of bytes is pushed onto the stack.
1163
+ def op_0
1164
+ @stack << "" # []
1165
+ end
1166
+
1167
+ # The number 1 is pushed onto the stack. Same as OP_TRUE
1168
+ def op_1
1169
+ @stack << 1
1170
+ end
1171
+
1172
+ # Returns the smaller of a and b.
1173
+ def op_min
1174
+ @stack << pop_int(2).min
1175
+ end
1176
+
1177
+ # Returns the larger of a and b.
1178
+ def op_max
1179
+ @stack << pop_int(2).max
1180
+ end
1181
+
1182
+ # Copies the pair of items two spaces back in the stack to the front.
1183
+ def op_2over
1184
+ @stack << @stack[-4]
1185
+ @stack << @stack[-4]
1186
+ end
1187
+
1188
+ # Swaps the top two pairs of items.
1189
+ def op_2swap
1190
+ p1 = @stack.pop(2)
1191
+ p2 = @stack.pop(2)
1192
+ @stack += p1 += p2
1193
+ end
1194
+
1195
+ # If the input is true, duplicate it.
1196
+ def op_ifdup
1197
+ if cast_to_bool(@stack.last) == true
1198
+ @stack << @stack.last
1199
+ end
1200
+ end
1201
+
1202
+ # The number -1 is pushed onto the stack.
1203
+ def op_1negate
1204
+ @stack << -1
1205
+ end
1206
+
1207
+ # Puts the number of stack items onto the stack.
1208
+ def op_depth
1209
+ @stack << @stack.size
1210
+ end
1211
+
1212
+ # Returns 1 if x is within the specified range (left-inclusive), 0 otherwise.
1213
+ def op_within
1214
+ bn1, bn2, bn3 = pop_int(3)
1215
+ @stack << ( (bn2 <= bn1 && bn1 < bn3) ? 1 : 0 )
1216
+ end
1217
+
1218
+ # Returns 1 if the numbers are equal, 0 otherwise.
1219
+ def op_numequal
1220
+ a, b = pop_int(2)
1221
+ @stack << (a == b ? 1 : 0)
1222
+ end
1223
+
1224
+ # Returns 1 if the numbers are not equal, 0 otherwise.
1225
+ def op_numnotequal
1226
+ a, b = pop_int(2)
1227
+ @stack << (a != b ? 1 : 0)
1228
+ end
1229
+
1230
+ # Marks transaction as invalid.
1231
+ def op_return
1232
+ @script_invalid = true; nil
1233
+ end
1234
+
1235
+ # Copies the second-to-top stack item to the top.
1236
+ def op_over
1237
+ item = @stack[-2]
1238
+ @stack << item if item
1239
+ end
1240
+
1241
+ # If the top stack value is not 0, the statements are executed. The top stack value is removed.
1242
+ def op_if
1243
+ value = false
1244
+ if @do_exec
1245
+ (invalid; return) if @stack.size < 1
1246
+ value = cast_to_bool(pop_string) == false ? false : true
1247
+ end
1248
+ @exec_stack << value
1249
+ end
1250
+
1251
+ # If the top stack value is 0, the statements are executed. The top stack value is removed.
1252
+ def op_notif
1253
+ value = false
1254
+ if @do_exec
1255
+ (invalid; return) if @stack.size < 1
1256
+ value = cast_to_bool(pop_string) == false ? true : false
1257
+ end
1258
+ @exec_stack << value
1259
+ end
1260
+
1261
+ # If the preceding OP_IF or OP_NOTIF or OP_ELSE was not executed then these statements are and if the preceding OP_IF or OP_NOTIF or OP_ELSE was executed then these statements are not.
1262
+ def op_else
1263
+ return if @exec_stack.empty?
1264
+ @exec_stack[-1] = !@exec_stack[-1]
1265
+ end
1266
+
1267
+ # Ends an if/else block.
1268
+ def op_endif
1269
+ return if @exec_stack.empty?
1270
+ @exec_stack.pop
1271
+ end
1272
+
1273
+ # The item n back in the stack is copied to the top.
1274
+ def op_pick
1275
+ return invalid if @stack.size < 2
1276
+ pos = pop_int
1277
+ return invalid if (pos < 0) || (pos >= @stack.size)
1278
+ item = @stack[-(pos+1)]
1279
+ @stack << item if item
1280
+ end
1281
+
1282
+ # The fifth and sixth items back are moved to the top of the stack.
1283
+ def op_2rot
1284
+ return invalid if @stack.size < 6
1285
+ @stack[-6..-1] = [ *@stack[-4..-1], *@stack[-6..-5] ]
1286
+ end
1287
+
1288
+ # The item n back in the stack is moved to the top.
1289
+ def op_roll
1290
+ return invalid if @stack.size < 2
1291
+ pos = pop_int
1292
+ return invalid if (pos < 0) || (pos >= @stack.size)
1293
+ idx = -(pos+1)
1294
+ item = @stack[idx]
1295
+ if item
1296
+ @stack.delete_at(idx)
1297
+ @stack << item if item
1298
+ end
1299
+ end
1300
+
1301
+ # The top three items on the stack are rotated to the left.
1302
+ def op_rot
1303
+ return if @stack.size < 3
1304
+ @stack[-3..-1] = [ @stack[-2], @stack[-1], @stack[-3] ]
1305
+ end
1306
+
1307
+ # Removes the top two stack items.
1308
+ def op_2drop
1309
+ @stack.pop(2)
1310
+ end
1311
+
1312
+ # Duplicates the top two stack items.
1313
+ def op_2dup
1314
+ @stack.push(*@stack[-2..-1])
1315
+ end
1316
+
1317
+ # Duplicates the top three stack items.
1318
+ def op_3dup
1319
+ @stack.push(*@stack[-3..-1])
1320
+ end
1321
+
1322
+ # Removes the second-to-top stack item.
1323
+ def op_nip
1324
+ @stack.delete_at(-2)
1325
+ end
1326
+
1327
+ # Returns the length of the input string.
1328
+ def op_size
1329
+ item = @stack[-1]
1330
+ size = case item
1331
+ when String; item.bytesize
1332
+ when Numeric; OpenSSL::BN.new(item.to_s).to_mpi.size - 4
1333
+ end
1334
+ @stack << size
1335
+ end
1336
+
1337
+ # Transaction is invalid unless occuring in an unexecuted OP_IF branch
1338
+ def op_ver
1339
+ invalid if @do_exec
1340
+ end
1341
+
1342
+ def pop_int(count=nil)
1343
+ return cast_to_bignum(@stack.pop) unless count
1344
+ @stack.pop(count).map{|i| cast_to_bignum(i) }
1345
+ end
1346
+
1347
+ def pop_string(count=nil)
1348
+ return cast_to_string(@stack.pop) unless count
1349
+ @stack.pop(count).map{|i| cast_to_string(i) }
1350
+ end
1351
+
1352
+ def cast_to_bignum(buf)
1353
+ return (invalid; 0) unless buf
1354
+ case buf
1355
+ when Numeric
1356
+ invalid if OpenSSL::BN.new(buf.to_s).to_s(0).unpack("N")[0] > 4
1357
+ buf
1358
+ when String
1359
+ invalid if buf.bytesize > 4
1360
+ OpenSSL::BN.new([buf.bytesize].pack("N") + buf.reverse, 0).to_i
1361
+ else; raise TypeError, 'cast_to_bignum: failed to cast: %s (%s)' % [buf, buf.class]
1362
+ end
1363
+ end
1364
+
1365
+ def cast_to_string(buf)
1366
+ return (invalid; "") unless buf
1367
+ case buf
1368
+ when Numeric; OpenSSL::BN.new(buf.to_s).to_s(0)[4..-1].reverse
1369
+ when String; buf;
1370
+ else; raise TypeError, 'cast_to_string: failed to cast: %s (%s)' % [buf, buf.class]
1371
+ end
1372
+ end
1373
+
1374
+ def cast_to_bool(buf)
1375
+ buf = cast_to_string(buf).unpack("C*")
1376
+ size = buf.size
1377
+ buf.each.with_index{|byte,index|
1378
+ if byte != 0
1379
+ # Can be negative zero
1380
+ if (index == (size-1)) && byte == 0x80
1381
+ return false
1382
+ else
1383
+ return true
1384
+ end
1385
+ end
1386
+ }
1387
+ return false
1388
+ end
1389
+
1390
+ # Same as OP_NUMEQUAL, but runs OP_VERIFY afterward.
1391
+ def op_numequalverify
1392
+ op_numequal; op_verify
1393
+ end
1394
+
1395
+ # All of the signature checking words will only match signatures
1396
+ # to the data after the most recently-executed OP_CODESEPARATOR.
1397
+ def op_codeseparator
1398
+ @codehash_start = @chunks.size - @chunks.reverse.index(OP_CODESEPARATOR)
1399
+ @last_codeseparator_index = @chunk_last_index
1400
+ end
1401
+
1402
+ def codehash_script(opcode)
1403
+ # CScript scriptCode(pbegincodehash, pend);
1404
+ script = to_string(@chunks[(@codehash_start||0)...@chunks.size-@chunks.reverse.index(opcode)])
1405
+ checkhash = Bitcoin.hash160(Bitcoin::Script.binary_from_string(script).unpack("H*")[0])
1406
+ [script, checkhash]
1407
+ end
1408
+
1409
+
1410
+ # do a CHECKSIG operation on the current stack,
1411
+ # asking +check_callback+ to do the actual signature verification.
1412
+ # This is used by Protocol::Tx#verify_input_signature
1413
+ def op_checksig(check_callback, opts={})
1414
+ return invalid if @stack.size < 2
1415
+ pubkey = cast_to_string(@stack.pop)
1416
+ return (@stack << 0) unless Bitcoin::Script.check_pubkey_encoding?(pubkey, opts)
1417
+ drop_sigs = [ cast_to_string(@stack[-1]) ]
1418
+
1419
+ signature = cast_to_string(@stack.pop)
1420
+ return invalid unless Bitcoin::Script.check_signature_encoding?(signature, opts)
1421
+ return (@stack << 0) if signature == ""
1422
+
1423
+ sig, hash_type = parse_sig(signature)
1424
+
1425
+ subscript = sighash_subscript(drop_sigs, opts)
1426
+
1427
+ if check_callback == nil # for tests
1428
+ @stack << 1
1429
+ else # real signature check callback
1430
+ @stack <<
1431
+ ((check_callback.call(pubkey, sig, hash_type, subscript) == true) ? 1 : 0)
1432
+ end
1433
+ end
1434
+
1435
+ def sighash_subscript(drop_sigs, opts = {})
1436
+ if opts[:fork_id]
1437
+ drop_sigs.reject! do |signature|
1438
+ if signature && signature.size > 0
1439
+ _, hash_type = parse_sig(signature)
1440
+ (hash_type&SIGHASH_TYPE[:forkid]) != 0
1441
+ end
1442
+ end
1443
+ end
1444
+
1445
+ if inner_p2sh? && @inner_script_code
1446
+ ::Bitcoin::Script.new(@inner_script_code).to_binary_without_signatures(drop_sigs)
1447
+ else
1448
+ to_binary_without_signatures(drop_sigs)
1449
+ end
1450
+ end
1451
+
1452
+ # Same as OP_CHECKSIG, but OP_VERIFY is executed afterward.
1453
+ def op_checksigverify(check_callback, opts={})
1454
+ op_checksig(check_callback, opts)
1455
+ op_verify
1456
+ end
1457
+
1458
+ # do a CHECKMULTISIG operation on the current stack,
1459
+ # asking +check_callback+ to do the actual signature verification.
1460
+ #
1461
+ # CHECKMULTISIG does a m-of-n signatures verification on scripts of the form:
1462
+ # 0 <sig1> <sig2> | 2 <pub1> <pub2> 2 OP_CHECKMULTISIG
1463
+ # 0 <sig1> <sig2> | 2 <pub1> <pub2> <pub3> 3 OP_CHECKMULTISIG
1464
+ # 0 <sig1> <sig2> <sig3> | 3 <pub1> <pub2> <pub3> 3 OP_CHECKMULTISIG
1465
+ #
1466
+ # see https://en.bitcoin.it/wiki/BIP_0011 for details.
1467
+ # see https://github.com/bitcoin/bitcoin/blob/master/src/script.cpp#L931
1468
+ #
1469
+ # TODO: validate signature order
1470
+ # TODO: take global opcode count
1471
+ def op_checkmultisig(check_callback, opts={})
1472
+ return invalid if @stack.size < 1
1473
+ n_pubkeys = pop_int
1474
+ return invalid unless (0..20).include?(n_pubkeys)
1475
+ #return invalid if (nOpCount += n_pubkeys) > 201
1476
+ return invalid if @stack.size < n_pubkeys
1477
+ pubkeys = pop_string(n_pubkeys)
1478
+
1479
+ return invalid if @stack.size < 1
1480
+ n_sigs = pop_int
1481
+ return invalid if n_sigs < 0 || n_sigs > n_pubkeys
1482
+ return invalid if @stack.size < n_sigs
1483
+ sigs = pop_string(n_sigs)
1484
+ drop_sigs = sigs.dup
1485
+
1486
+ # Bitcoin-core removes an extra item from the stack
1487
+ @stack.pop
1488
+
1489
+ subscript = sighash_subscript(drop_sigs, opts)
1490
+
1491
+ success = true
1492
+ while success && n_sigs > 0
1493
+ sig, pub = sigs.pop, pubkeys.pop
1494
+ return (@stack << 0) unless Bitcoin::Script.check_pubkey_encoding?(pub, opts)
1495
+ return invalid unless Bitcoin::Script.check_signature_encoding?(sig, opts)
1496
+ unless sig && sig.size > 0
1497
+ success = false
1498
+ break
1499
+ end
1500
+ signature, hash_type = parse_sig(sig)
1501
+ if pub.size > 0 && check_callback.call(pub, signature, hash_type, subscript)
1502
+ n_sigs -= 1
1503
+ else
1504
+ sigs << sig
1505
+ end
1506
+ n_pubkeys -= 1
1507
+ success = false if n_sigs > n_pubkeys
1508
+ end
1509
+
1510
+ @stack << (success ? 1 : 0)
1511
+ end
1512
+
1513
+ # Same as OP_CHECKMULTISIG, but OP_VERIFY is executed afterward.
1514
+ def op_checkmultisigverify(check_callback, opts={})
1515
+ op_checkmultisig(check_callback, opts)
1516
+ op_verify
1517
+ end
1518
+
1519
+ # op_eval: https://en.bitcoin.it/wiki/BIP_0012
1520
+ # the BIP was never accepted and must be handled as old OP_NOP1
1521
+ def op_nop1
1522
+ end
1523
+
1524
+ OPCODES_METHOD = Hash[*instance_methods.grep(/^op_/).map{|m|
1525
+ [ (OPCODES.find{|k,v| v == m.to_s.upcase }.first rescue nil), m ]
1526
+ }.flatten]
1527
+ OPCODES_METHOD[0] = :op_0
1528
+ OPCODES_METHOD[81] = :op_1
1529
+
1530
+ def self.check_pubkey_encoding?(pubkey, opts={})
1531
+ return false if opts[:verify_strictenc] && !is_compressed_or_uncompressed_pub_key?(pubkey)
1532
+ true
1533
+ end
1534
+
1535
+ def self.is_compressed_or_uncompressed_pub_key?(pubkey)
1536
+ return false if pubkey.bytesize < 33 # "Non-canonical public key: too short"
1537
+ case pubkey[0]
1538
+ when "\x04"
1539
+ return false if pubkey.bytesize != 65 # "Non-canonical public key: invalid length for uncompressed key"
1540
+ when "\x02", "\x03"
1541
+ return false if pubkey.bytesize != 33 # "Non-canonical public key: invalid length for compressed key"
1542
+ else
1543
+ return false # "Non-canonical public key: compressed nor uncompressed"
1544
+ end
1545
+ true
1546
+ end
1547
+
1548
+ # Loosely matches CheckSignatureEncoding()
1549
+ def self.check_signature_encoding?(sig, opts={})
1550
+ return true if sig.bytesize == 0
1551
+ return false if (opts[:verify_dersig] || opts[:verify_low_s] || opts[:verify_strictenc]) and !is_der_signature?(sig)
1552
+ return false if opts[:verify_low_s] && !is_low_der_signature?(sig)
1553
+
1554
+ if opts[:verify_strictenc]
1555
+ return false unless is_defined_hashtype_signature?(sig)
1556
+
1557
+ hash_type = sig.unpack('C*')[-1]
1558
+ uses_forkid = (hash_type&SIGHASH_TYPE[:forkid]) != 0
1559
+ return false if opts[:fork_id] && !uses_forkid
1560
+ return false if !opts[:fork_id] && uses_forkid
1561
+ end
1562
+
1563
+ true
1564
+ end
1565
+
1566
+ # Loosely correlates with IsDERSignature() from interpreter.cpp
1567
+ def self.is_der_signature?(sig)
1568
+ return false if sig.bytesize < 9 # Non-canonical signature: too short
1569
+ return false if sig.bytesize > 73 # Non-canonical signature: too long
1570
+
1571
+ s = sig.unpack("C*")
1572
+
1573
+ return false if s[0] != 0x30 # Non-canonical signature: wrong type
1574
+ return false if s[1] != s.size-3 # Non-canonical signature: wrong length marker
1575
+
1576
+ length_r = s[3]
1577
+ return false if (5 + length_r) >= s.size # Non-canonical signature: S length misplaced
1578
+ length_s = s[5+length_r]
1579
+ return false if (length_r + length_s + 7) != s.size # Non-canonical signature: R+S length mismatch
1580
+
1581
+ return false if s[2] != 0x02 # Non-canonical signature: R value type mismatch
1582
+
1583
+ return false if length_r == 0 # Non-canonical signature: R length is zero
1584
+
1585
+ r_val = s.slice(4, length_r)
1586
+ return false if r_val[0] & 0x80 != 0 # Non-canonical signature: R value negative
1587
+
1588
+ return false if length_r > 1 && (r_val[0] == 0x00) && !(r_val[1] & 0x80 != 0) # Non-canonical signature: R value excessively padded
1589
+
1590
+ s_val = s.slice(6 + length_r, length_s)
1591
+ return false if s[6 + length_r - 2] != 0x02 # Non-canonical signature: S value type mismatch
1592
+
1593
+ return false if length_s == 0 # Non-canonical signature: S length is zero
1594
+ return false if (s_val[0] & 0x80) != 0 # Non-canonical signature: S value negative
1595
+
1596
+ return false if length_s > 1 && (s_val[0] == 0x00) && !(s_val[1] & 0x80) # Non-canonical signature: S value excessively padded
1597
+
1598
+ true
1599
+ end
1600
+
1601
+ # Compares two arrays of bytes
1602
+ def self.compare_big_endian(c1, c2)
1603
+ c1, c2 = c1.dup, c2.dup # Clone the arrays
1604
+
1605
+ while c1.size > c2.size
1606
+ return 1 if c1.shift > 0
1607
+ end
1608
+
1609
+ while c2.size > c1.size
1610
+ return -1 if c2.shift > 0
1611
+ end
1612
+
1613
+ c1.size.times{|idx| return c1[idx] - c2[idx] if c1[idx] != c2[idx] }
1614
+ 0
1615
+ end
1616
+
1617
+ # Loosely correlates with IsLowDERSignature() from interpreter.cpp
1618
+ def self.is_low_der_signature?(sig)
1619
+ s = sig.unpack("C*")
1620
+
1621
+ length_r = s[3]
1622
+ length_s = s[5+length_r]
1623
+ s_val = s.slice(6 + length_r, length_s)
1624
+
1625
+ # If the S value is above the order of the curve divided by two, its
1626
+ # complement modulo the order could have been used instead, which is
1627
+ # one byte shorter when encoded correctly.
1628
+ max_mod_half_order = [
1629
+ 0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1630
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1631
+ 0x5d,0x57,0x6e,0x73,0x57,0xa4,0x50,0x1d,
1632
+ 0xdf,0xe9,0x2f,0x46,0x68,0x1b,0x20,0xa0]
1633
+
1634
+ compare_big_endian(s_val, [0]) > 0 &&
1635
+ compare_big_endian(s_val, max_mod_half_order) <= 0
1636
+ end
1637
+
1638
+ def self.is_defined_hashtype_signature?(sig)
1639
+ return false if sig.empty?
1640
+
1641
+ s = sig.unpack("C*")
1642
+ hash_type = s[-1] & (~(SIGHASH_TYPE[:anyonecanpay] | SIGHASH_TYPE[:forkid]))
1643
+ return false if hash_type < SIGHASH_TYPE[:all] || hash_type > SIGHASH_TYPE[:single] # Non-canonical signature: unknown hashtype byte
1644
+
1645
+ true
1646
+ end
1647
+
1648
+
1649
+ private
1650
+
1651
+ def parse_sig(sig)
1652
+ hash_type = sig[-1].unpack("C")[0]
1653
+ sig = sig[0...-1]
1654
+ return sig, hash_type
1655
+ end
1656
+ end