abiDecodeString function

String abiDecodeString(
  1. String hexData
)

Decodes an ABI-encoded dynamic string (offset + length + data).

Returns an empty string when hexData is too short, malformed, or declares a length that exceeds the actual payload. Callers can rely on this function never throwing for untrusted on-chain data.

Implementation

String abiDecodeString(String hexData) {
  final clean = hexData.startsWith('0x') ? hexData.substring(2) : hexData;
  if (clean.length < 128) return '';

  // Word 0: offset (should be 0x20 = 32)
  // Word 1: length
  final lengthHex = clean.substring(64, 128);
  final int length;
  try {
    length = int.parse(lengthHex, radix: 16);
  } on FormatException catch (_) {
    return '';
  }
  if (length <= 0) return '';

  // Data starts at hex char offset 128. Guard against contracts that declare
  // a longer string than they actually pack — without this check,
  // `substring(128, 128 + length * 2)` would throw RangeError for truncated
  // payloads and escape through callers that assume ABI decode is total.
  final int dataEnd = 128 + length * 2;
  if (clean.length < dataEnd) return '';

  final dataHex = clean.substring(128, dataEnd);
  final bytes = <int>[];
  for (int i = 0; i < dataHex.length; i += 2) {
    try {
      bytes.add(int.parse(dataHex.substring(i, i + 2), radix: 16));
    } on FormatException catch (_) {
      return '';
    }
  }
  return String.fromCharCodes(bytes);
}