class Bitcoin::SigHashGenerator::LegacySigHashGenerator

Legacy SigHash Generator

Public Instance Methods

generate(tx, input_index, hash_type, opts) click to toggle source
# File lib/bitcoin/sighash_generator.rb, line 21
def generate(tx, input_index, hash_type, opts)
  output_script = opts[:script_code]
  ins = tx.inputs.map.with_index do |i, idx|
    if idx == input_index
      i.to_payload(output_script.delete_opcode(Bitcoin::Opcodes::OP_CODESEPARATOR))
    else
      case hash_type & 0x1f
      when SIGHASH_TYPE[:none], SIGHASH_TYPE[:single]
        i.to_payload(Bitcoin::Script.new, 0)
      else
        i.to_payload(Bitcoin::Script.new)
      end
    end
  end

  outs = tx.outputs.map(&:to_payload)
  out_size = Bitcoin.pack_var_int(tx.outputs.size)

  case hash_type & 0x1f
  when SIGHASH_TYPE[:none]
    outs = ''
    out_size = Bitcoin.pack_var_int(0)
  when SIGHASH_TYPE[:single]
    return "\x01".ljust(32, "\x00") if input_index >= tx.outputs.size
    outs = tx.outputs[0...(input_index + 1)].map.with_index { |o, idx| (idx == input_index) ? o.to_payload : o.to_empty_payload }.join
    out_size = Bitcoin.pack_var_int(input_index + 1)
  end

  ins = [ins[input_index]] unless hash_type & SIGHASH_TYPE[:anyonecanpay] == 0

  buf = [[tx.version].pack('V'), Bitcoin.pack_var_int(ins.size),
         ins, out_size, outs, [tx.lock_time, hash_type].pack('VV')].join

  Bitcoin.double_sha256(buf)
end