class Bitcoin::SigHashGenerator::SegwitSigHashGenerator

V0 witness sighash generator. see: github.com/bitcoin/bips/blob/master/bip-0143.mediawiki

Public Instance Methods

generate(tx, input_index, hash_type, opts) click to toggle source
# File lib/bitcoin/sighash_generator.rb, line 63
def generate(tx, input_index, hash_type, opts)
  amount = opts[:amount]
  output_script = opts[:script_code]
  skip_separator_index = opts[:skip_separator_index]
  hash_prevouts = Bitcoin.double_sha256(tx.inputs.map{|i|i.out_point.to_payload}.join)
  hash_sequence = Bitcoin.double_sha256(tx.inputs.map{|i|[i.sequence].pack('V')}.join)
  outpoint = tx.inputs[input_index].out_point.to_payload
  amount = [amount].pack('Q')
  nsequence = [tx.inputs[input_index].sequence].pack('V')
  hash_outputs = Bitcoin.double_sha256(tx.outputs.map{|o|o.to_payload}.join)

  script_code = output_script.to_script_code(skip_separator_index)

  case (hash_type & 0x1f)
  when SIGHASH_TYPE[:single]
    hash_outputs = input_index >= tx.outputs.size ? "\x00".ljust(32, "\x00") : Bitcoin.double_sha256(tx.outputs[input_index].to_payload)
    hash_sequence = "\x00".ljust(32, "\x00")
  when SIGHASH_TYPE[:none]
    hash_sequence = hash_outputs = "\x00".ljust(32, "\x00")
  end

  unless (hash_type & SIGHASH_TYPE[:anyonecanpay]) == 0
    hash_prevouts = hash_sequence ="\x00".ljust(32, "\x00")
  end

  buf = [ [tx.version].pack('V'), hash_prevouts, hash_sequence, outpoint,
          script_code ,amount, nsequence, hash_outputs, [tx.lock_time, hash_type].pack('VV')].join
  Bitcoin.double_sha256(buf)
end