Commit 997852bfb3d136013f1cb0890436e27c525d5917

Authored by Marius Hanne
1 parent cfa20c8eb5
Exists in p2sh

p2sh

Showing 2 changed files with 31 additions and 0 deletions Side-by-side Diff

lib/bitcoin/script.rb
... ... @@ -261,6 +261,7 @@
261 261  
262 262 # run the script. +check_callback+ is called for OP_CHECKSIG operations
263 263 def run(&check_callback)
  264 + return pay_to_script_hash(check_callback) if is_p2sh?
264 265 @debug = []
265 266 @chunks.each{|chunk|
266 267 break if invalid?
... ... @@ -354,6 +355,25 @@
354 355  
355 356 @stack << 1 if valid_sigs >= n_sigs
356 357 end
  358 +
  359 + # pay_to_script_hash: https://en.bitcoin.it/wiki/BIP_0016
  360 + #
  361 + # <sig> {<pub> OP_CHECKSIG} | OP_HASH160 <script_hash> OP_EQUAL
  362 + def pay_to_script_hash(check_callback)
  363 + script_hash = @chunks[-2]
  364 + script = @chunks[-4]
  365 + sig = Script.from_string(@chunks[0].unpack("H*")[0]).raw
  366 +
  367 + return false unless Bitcoin.hash160(script.unpack("H*")[0]) == script_hash.unpack("H*")[0]
  368 + script = Script.new(sig + script)
  369 + script.run(&check_callback)
  370 + end
  371 +
  372 + def is_pay_to_script_hash?
  373 + @chunks.size >= 4 && @chunks[-3] == OP_HASH160 &&
  374 + @chunks[-2].bytesize == 20 && @chunks[-1] == OP_EQUAL
  375 + end
  376 + alias :is_p2sh? :is_pay_to_script_hash?
357 377  
358 378 def is_standard? # TODO: add
359 379 # https://github.com/bitcoin/bitcoin/blob/master/src/script.cpp#L967
spec/bitcoin/script_spec.rb
... ... @@ -372,6 +372,17 @@
372 372 # run_script(script, "foobar").should == false
373 373 end
374 374  
  375 + it "should do P2SH" do
  376 + k1 = Bitcoin::Key.new; k1.generate
  377 + sig = (k1.sign("foobar") + "\x01").unpack("H*")[0]
  378 + inner_script = Bitcoin::Script.from_string("#{k1.pub} OP_CHECKSIG").raw.unpack("H*")[0]
  379 + script_hash = Bitcoin.hash160(inner_script)
  380 + script = "#{sig} #{inner_script} OP_HASH160 #{script_hash} OP_EQUAL"
  381 +
  382 + Bitcoin::Script.from_string(script).is_p2sh?.should == true
  383 + run_script(script, "foobar").should == true
  384 + end
  385 +
375 386 end
376 387  
377 388 end