monacoin-ruby 0.1.2 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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