hashForSignature method

dynamic hashForSignature(
  1. int inIndex,
  2. Uint8List? prevOutScript,
  3. int hashType
)

Implementation

hashForSignature(int inIndex, Uint8List? prevOutScript, int hashType) {
  if (inIndex >= ins.length) return ONE;
  // ignore OP_CODESEPARATOR
  final ourScript =
      bscript.compile(bscript.decompile(prevOutScript)!.where((x) {
    return x != OPS['OP_CODESEPARATOR'];
  }).toList());
  final txTmp = Transaction.clone(this);
  // SIGHASH_NONE: ignore all outputs? (wildcard payee)
  if ((hashType & 0x1f) == SIGHASH_NONE) {
    txTmp.outs = [];
    // ignore sequence numbers (except at inIndex)
    for (var i = 0; i < txTmp.ins.length; i++) {
      if (i != inIndex) {
        txTmp.ins[i].sequence = 0;
      }
    }

    // SIGHASH_SINGLE: ignore all outputs, except at the same index?
  } else if ((hashType & 0x1f) == SIGHASH_SINGLE) {
    // https://github.com/bitcoin/bitcoin/blob/master/src/test/sighash_tests.cpp#L60
    if (inIndex >= outs.length) return ONE;

    // truncate outputs after
    txTmp.outs.length = inIndex + 1;

    // 'blank' outputs before
    for (var i = 0; i < inIndex; i++) {
      txTmp.outs[i] = BLANK_OUTPUT;
    }
    // ignore sequence numbers (except at inIndex)
    for (var i = 0; i < txTmp.ins.length; i++) {
      if (i != inIndex) {
        txTmp.ins[i].sequence = 0;
      }
    }
  }

  // SIGHASH_ANYONECANPAY: ignore inputs entirely?
  if (hashType & SIGHASH_ANYONECANPAY != 0) {
    txTmp.ins = [txTmp.ins[inIndex]];
    txTmp.ins[0].script = ourScript;
    // SIGHASH_ALL: only ignore input scripts
  } else {
    // 'blank' others input scripts
    txTmp.ins.forEach((input) {
      input.script = EMPTY_SCRIPT;
    });
    txTmp.ins[inIndex].script = ourScript;
  }
  // serialize and hash
  final buffer = Uint8List(txTmp.virtualSize() + 4);
  buffer.buffer
      .asByteData()
      .setUint32(buffer.length - 4, hashType, Endian.little);
  txTmp._toBuffer(buffer, 0);
  return bcrypto.hash256(buffer);
}