BTCRawTransaction.fromHex constructor

BTCRawTransaction.fromHex(
  1. String hex
)

Implementation

factory BTCRawTransaction.fromHex(String hex) {
  final buffer = hex.hexToBytes;

  var offset = 0;

  /// Version
  final (version, length) = buffer.bytes.readUint32(offset);
  offset += length;

  /// Segwit Flag
  final isSegwit =
      buffer[offset] == SEGWIT_MARKER && buffer[offset + 1] == SEGWIT_FLAG;

  if (isSegwit) {
    offset += 2;
  }

  /// Inputs
  final (inputLength, inputLengthByteLength) =
      buffer.bytes.readVarInt(offset);
  offset += inputLengthByteLength;

  final inputs = <BTCInput>[];
  for (int i = 0; i < inputLength; i++) {
    final input = BTCInput.fromBuffer(buffer.sublist(offset));
    offset += input.size;
    inputs.add(input);
  }

  /// Outputs
  final (outputLength, outputLengthByteLength) =
      buffer.bytes.readVarInt(offset);
  offset += outputLengthByteLength;

  final outputs = <BTCOutput>[];

  for (int i = 0; i < outputLength; i++) {
    final output = BTCOutput.fromBuffer(buffer.sublist(offset));
    offset += output.size;
    outputs.add(output);
  }

  /// Witness
  if (isSegwit) {
    List<(Uint8List, BTCInput)> wittnessScripts = [];

    for (final input in inputs) {
      final (emptyScript, emptyScriptLength) = buffer.bytes.readUint8(offset);
      if (emptyScript == 0x00) {
        offset += emptyScriptLength;
        continue;
      }

      final (wittnessScript, length) =
          readScriptWittness(buffer: buffer, offset: offset);
      wittnessScripts.add((wittnessScript, input));
      offset += length;
    }

    for (final (wittnessScript, input) in wittnessScripts) {
      final index = inputs.indexOf(input);
      inputs[index] = input.addScript(wittnessScript: wittnessScript);
    }
  }

  /// Locktime
  final (lockTime, _) = buffer.bytes.readUint32(offset);

  return BTCRawTransaction(
    version: version,
    lockTime: lockTime,
    inputs: inputs,
    outputs: outputs,
  );
}