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.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 = new P2PKH(
                data: new 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) {
    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');
}