sign method

dynamic sign({
  1. required int vin,
  2. required ECPair keyPair,
  3. Uint8List? redeemScript,
  4. int? witnessValue,
  5. Uint8List? witnessScript,
  6. int? hashType,
})

Implementation

sign({
  required int vin,
  required ECPair keyPair,
  Uint8List? redeemScript,
  int? witnessValue,
  Uint8List? witnessScript,
  int? hashType,
}) {
  if (keyPair.network != null && keyPair.network.toString().compareTo(network.toString()) != 0)
    throw new ArgumentError('Inconsistent network');
  if (vin >= _inputs.length) throw new ArgumentError('No input at index: $vin');
  hashType = hashType ?? SIGHASH_ALL;
  if (this._needsOutputs(hashType)) throw new ArgumentError('Transaction needs outputs');
  final input = _inputs[vin];
  final ourPubKey = keyPair.publicKey;
  if (!_canSign(input)) {
    if (witnessValue != null) {
      input.value = witnessValue;
    }
    if (redeemScript != null && witnessScript != null) {
      // TODO p2wsh
    }
    if (redeemScript != null) {
      // TODO
    }
    if (witnessScript != null) {
      // TODO
    }
    if (input.prevOutScript != null && input.prevOutType != null) {
      var type = classifyOutput(input.prevOutScript!);
      if (type == SCRIPT_TYPES['P2WPKH']) {
        input.prevOutType = SCRIPT_TYPES['P2WPKH']!;
        input.hasWitness = true;
        input.signatures = [null];
        input.pubkeys = [ourPubKey];
        input.signScript =
            P2PKH(data: PaymentData(pubkey: ourPubKey), network: this.network).data.output!;
      } else {
        // DRY CODE
        Uint8List prevOutScript = pubkeyToOutputScript(ourPubKey);
        input.prevOutType = SCRIPT_TYPES['P2PKH']!;
        input.signatures = [null];
        input.pubkeys = [ourPubKey];
        input.signScript = prevOutScript;
      }
    } else {
      Uint8List prevOutScript = pubkeyToOutputScript(ourPubKey);
      input.prevOutType = SCRIPT_TYPES['P2PKH']!;
      input.signatures = [null];
      input.pubkeys = [ourPubKey];
      input.signScript = prevOutScript;
    }
  }
  var signatureHash;
  if (input.hasWitness ?? false) {
    signatureHash = this._tx.hashForWitnessV0(vin, input.signScript!, input.value!, hashType);
  } else {
    signatureHash = this._tx.hashForSignature(vin, input.signScript!, hashType);
  }

  // enforce in order signing of public keys
  var signed = false;
  for (var i = 0; i < input.pubkeys!.length; i++) {
    if (HEX.encode(ourPubKey).compareTo(HEX.encode(input.pubkeys![i]!)) != 0) continue;

    if (input.signatures?[i] != null) throw new ArgumentError('Signature already exists');

    final signature = keyPair.sign(signatureHash);
    input.signatures?[i] = bscript.encodeSignature(signature, hashType);
    signed = true;
  }
  if (!signed) throw new ArgumentError('Key pair cannot sign for this input');
}