lib/bitcoin/script.rb
# do a CHECKMULTISIG operation on the current stack,
# asking +check_callback+ to do the actual signature verification.
#
# CHECKMULTISIG does a m-of-n signatures verification on scripts of the form:
#  0 <sig1> <sig2> | 2 <pub1> <pub2> 2 OP_CHECKMULTISIG
#  0 <sig1> <sig2> | 2 <pub1> <pub2> <pub3> 3 OP_CHECKMULTISIG
#  0 <sig1> <sig2> <sig3> | 3 <pub1> <pub2> <pub3> 3 OP_CHECKMULTISIG
#
# see https://en.bitcoin.it/wiki/BIP_0011 for details.
# see https://github.com/bitcoin/bitcoin/blob/master/src/script.cpp#L931
#
# TODO: validate signature order
# TODO: take global opcode count
do a CHECKMULTISIG operation on the current stack,
asking +check_callback+ to do the actual signature verification.

CHECKMULTISIG does a m-of-n signatures verification on scripts of the form:
0   | 2   2 OP_CHECKMULTISIG
0   | 2    3 OP_CHECKMULTISIG
0    | 3    3 OP_CHECKMULTISIG



validate signature order
TODO: take global opcode count
do a CHECKMULTISIG operation on the current stack asking + check_callback + to do the actual signature verification . CHECKMULTISIG does a m - of - n signatures verification on scripts of the form : 0 | 2 2 OP_CHECKMULTISIG 0 | 2 3 OP_CHECKMULTISIG 0 | 3 3 OP_CHECKMULTISIG validate signature order TODO : take global opcode count
def op_checkmultisig(check_callback, opts={})
    return invalid if @stack.size < 1
    n_pubkeys = pop_int
    return invalid  unless (0..20).include?(n_pubkeys)
    return invalid if @stack.size < n_pubkeys
    pubkeys = pop_string(n_pubkeys)
    return invalid if @stack.size < 1
    n_sigs = pop_int
    return invalid if n_sigs < 0 || n_sigs > n_pubkeys
    return invalid if @stack.size < n_sigs
    sigs = pop_string(n_sigs)
    drop_sigs = sigs.dup
    @stack.pop
    subscript = sighash_subscript(drop_sigs, opts)
    success = true
    while success && n_sigs > 0
      sig, pub = sigs.pop, pubkeys.pop
      return (@stack << 0) unless Bitcoin::Script.check_pubkey_encoding?(pub, opts)
      return invalid unless Bitcoin::Script.check_signature_encoding?(sig, opts)
      unless sig && sig.size > 0
        success = false
        break
      end
      signature, hash_type = parse_sig(sig)
      if pub.size > 0 && check_callback.call(pub, signature, hash_type, subscript)
        n_sigs -= 1
      else
        sigs << sig
      end
      n_pubkeys -= 1
      success = false if n_sigs > n_pubkeys
    end
    @stack << (success ? 1 : 0)
  end
def op_checkmultisig ( check_callback , opts = { } ) return invalid if @stack . size < 1 n_pubkeys = pop_int return invalid unless ( 0 .. 20 ) . include? ( n_pubkeys ) return invalid if @stack . size < n_pubkeys pubkeys = pop_string ( n_pubkeys ) return invalid if @stack . size < 1 n_sigs = pop_int return invalid if n_sigs < 0 || n_sigs > n_pubkeys return invalid if @stack . size < n_sigs sigs = pop_string ( n_sigs ) drop_sigs = sigs . dup @stack . pop subscript = sighash_subscript ( drop_sigs , opts ) success = true while success && n_sigs > 0 sig , pub = sigs . pop , pubkeys . pop return ( @stack << 0 ) unless Bitcoin :: Script . check_pubkey_encoding? ( pub , opts ) return invalid unless Bitcoin :: Script . check_signature_encoding? ( sig , opts ) unless sig && sig . size > 0 success = false break end signature , hash_type = parse_sig ( sig ) if pub . size > 0 && check_callback . call ( pub , signature , hash_type , subscript ) n_sigs -= 1 else sigs << sig end n_pubkeys -= 1 success = false if n_sigs > n_pubkeys end @stack << ( success ? 1 : 0 ) end
do a CHECKMULTISIG operation on the current stack,
asking +check_callback+ to do the actual signature verification.
do a CHECKMULTISIG operation on the current stack asking + check_callback + to do the actual signature verification .
#return invalid  if (nOpCount += n_pubkeys) > 201 # Bitcoin-core removes an extra item from the stack
check_callback
<not_specific>
opts
<not_specific>