bip143sigHash method

Uint8List bip143sigHash({
  1. required int index,
  2. required Uint8List prevScriptPubKey,
  3. required ElectrumOutput output,
  4. required int hashType,
})

BIP143 SigHash: https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki

Implementation

Uint8List bip143sigHash({
  required int index,
  required Uint8List prevScriptPubKey,
  required ElectrumOutput output,
  required int hashType,
}) {
  ///
  /// Always use P2PKH in bip143 sigHash
  ///
  final converter = PublicKeyScriptConverter(prevScriptPubKey);
  final p2pkhScript = converter.p2pkhScript;

  final outputBuffers = outputs.map((output) => output.bytes);
  final txOutSize = outputBuffers.fold(
    0,
    (prev, element) => prev + element.length,
  );

  ///
  /// Inputs
  ///
  var tBuffer = Uint8List(36 * inputs.length);
  var tOffset = 0;
  for (final input in inputs) {
    tOffset += tBuffer.writeSlice(tOffset, input.txid);
    tOffset += tBuffer.bytes.writeUint32(tOffset, input.vout);
  }

  final hashPrevouts = sha256Sha256Hash(tBuffer);

  tBuffer = Uint8List(4 * inputs.length);
  tOffset = 0;
  for (final input in inputs) {
    tOffset += tBuffer.bytes.writeUint32(tOffset, input.sequence);
  }
  final hashSequence = sha256Sha256Hash(tBuffer);

  /// Outputs

  tBuffer = Uint8List(txOutSize);
  tOffset = 0;

  for (final output in outputs) {
    tOffset += tBuffer.bytes.writeUint64(tOffset, output.value.toInt());
    tOffset += tBuffer.writeVarSlice(tOffset, output.scriptPubKey);
  }
  final hashOutputs = sha256Sha256Hash(tBuffer);

  /// Final Buffer
  final inputToSign = inputs[index];
  final prevScriptPubKeyLength = varSliceSize(p2pkhScript);
  tBuffer = Uint8List(156 + prevScriptPubKeyLength);
  tOffset = 0;

  tOffset += tBuffer.bytes.writeUint32(tOffset, version);
  tOffset += tBuffer.writeSlice(tOffset, hashPrevouts);
  tOffset += tBuffer.writeSlice(tOffset, hashSequence);

  tOffset += tBuffer.writeSlice(tOffset, inputToSign.txid);
  tOffset += tBuffer.bytes.writeUint32(tOffset, inputToSign.vout);

  tOffset += tBuffer.writeVarSlice(tOffset, p2pkhScript);

  tOffset += tBuffer.bytes.writeUint64(tOffset, output.value.toInt());
  tOffset += tBuffer.bytes.writeUint32(tOffset, inputToSign.sequence);

  tOffset += tBuffer.writeSlice(tOffset, hashOutputs);

  tOffset += tBuffer.bytes.writeUint32(tOffset, lockTime);
  tOffset += tBuffer.bytes.writeUint32(tOffset, hashType);

  final hash = sha256Sha256Hash(tBuffer);

  return hash;
}