getTypeAndHashFromOutputScript function

TypeAndHash getTypeAndHashFromOutputScript(
  1. String outputScript
)

Get type and hash from an outputScript

Supported outputScripts:

P2PKH: 76a914

Validates for supported outputScript and hash length

Implementation

TypeAndHash getTypeAndHashFromOutputScript(String outputScript) {
  const String p2pkhPrefix = '76a914';
  const String p2pkhSuffix = '88ac';

  const String p2shPrefix = 'a914';
  const String p2shSuffix = '87';

  late String hash;
  late AddressType type;

  // If outputScript begins with '76a914' and ends with '88ac'
  if (outputScript.substring(0, p2pkhPrefix.length) == p2pkhPrefix &&
      outputScript.substring(outputScript.length - p2pkhSuffix.length) ==
          p2pkhSuffix) {
    // We have type p2pkh
    type = AddressType.p2pkh;

    // hash is the string in between '76a914' and '88ac'
    hash = outputScript.substring(
      outputScript.indexOf(p2pkhPrefix) + p2pkhPrefix.length,
      outputScript.lastIndexOf(p2pkhSuffix),
    );
    // If outputScript begins with 'a914' and ends with '87'
  } else if (outputScript.substring(0, p2shPrefix.length) == p2shPrefix &&
      outputScript.substring(outputScript.length - p2shSuffix.length) ==
          p2shSuffix) {
    // We have type p2sh
    type = AddressType.p2sh;
    // hash is the string in between 'a914' and '87'
    hash = outputScript.substring(
      outputScript.indexOf(p2shPrefix) + p2shPrefix.length,
      outputScript.lastIndexOf(p2shSuffix),
    );
  } else {
    // Throw validation error if outputScript not of these two types
    throw ValidationError('Unsupported outputScript: $outputScript');
  }

  // Throw validation error if hash is of invalid size
  // Per spec, valid hash sizes in bytes
  const List<int> validSizes = [20, 24, 28, 32, 40, 48, 56, 64];

  if (!validSizes.contains(hash.length ~/ 2)) {
    throw ValidationError('Invalid hash size in outputScript: $outputScript');
  }
  return TypeAndHash(type: type, hash: hash);
}