encodeSingle static method

Uint8List encodeSingle(
  1. String type,
  2. dynamic arg
)

Implementation

static Uint8List encodeSingle(String type, dynamic arg) {
  var size, i;

  if (type == 'address') {
    return encodeSingle('uint160', parseNumber(arg));
  } else if (type == 'bool') {
    int? val;
    if (arg is int) {
      val = arg == 0 ? 0 : 1;
    } else if (arg is bool) {
      val = arg ? 1 : 0;
    } else if (arg is String) {
      val = arg.isEmpty ? 0 : 1;
    }
    return encodeSingle('uint8', val);
  } else if (type == 'string') {
    return encodeSingle('bytes', utf8.encode(arg));
  } else if (isArray(type)) {
    // this part handles fixed-length ([2]) and variable length ([]) arrays
    // NOTE: we catch here all calls to arrays, that simplifies the rest
    if (!(arg is List)) {
      throw new ArgumentError('Not an array?');
    }
    size = parseTypeArray(type);
    if (size != 'dynamic' && size != 0 && arg.length > size) {
      throw new ArgumentError('Elements exceed array size: ${size}');
    }
    var ret = BytesBuffer();
    type = type.substring(0, type.lastIndexOf('['));
    if (arg is String) {
      arg = jsonDecode(arg as String);
    }

    if (size == 'dynamic') {
      var length = encodeSingle('uint256', arg.length);
      ret.add(length);
    }
    arg.forEach((v) {
      ret.add(encodeSingle(type, v));
    });
    return ret.toBytes();
  } else if (type == 'bytes') {
    arg = toBuffer(arg);

    var ret = BytesBuffer();
    ret.add(encodeSingle('uint256', arg.length));
    ret.add(arg);

    final remainArgLength = (arg as Uint8List).length % 32;
    if (remainArgLength != 0) {
      ret.add(zeros(32 - remainArgLength));
    }

    return ret.toBytes();
  } else if (type.startsWith('bytes')) {
    size = parseTypeN(type);
    if (size < 1 || size > 32) {
      throw new ArgumentError('Invalid bytes<N> width: ${size}');
    }

    return setLengthRight(toBuffer(arg), 32);
  } else if (type.startsWith('uint')) {
    size = parseTypeN(type);
    if ((size % 8 > 0) || (size < 8) || (size > 256)) {
      throw new ArgumentError('Invalid uint<N> width: ${size}');
    }

    var num = parseNumber(arg);
    if (num.bitLength > size) {
      throw new ArgumentError(
          'Supplied uint exceeds width: ${size} vs ${num.bitLength}');
    }

    if (num < BigInt.zero) {
      throw new ArgumentError('Supplied uint is negative');
    }

    return encodeBigInt(num, length: 32);
  } else if (type.startsWith('int')) {
    size = parseTypeN(type);
    if ((size % 8 != 0) || (size < 8) || (size > 256)) {
      throw new ArgumentError('Invalid int<N> width: ${size}');
    }

    var num = parseNumber(arg);
    if (num.bitLength > size) {
      throw new ArgumentError(
          'Supplied int exceeds width: ${size} vs ${num.bitLength}');
    }

    return encodeBigInt(num.toUnsigned(256), length: 32);
  } else if (type.startsWith('ufixed')) {
    size = parseTypeNxM(type);

    var num = parseNumber(arg);

    if (num < BigInt.zero) {
      throw new ArgumentError('Supplied ufixed is negative');
    }

    return encodeSingle('uint256', num * BigInt.two.pow(size[1]));
  } else if (type.startsWith('fixed')) {
    size = parseTypeNxM(type);

    return encodeSingle('int256', parseNumber(arg) * BigInt.two.pow(size[1]));
  }

  throw new ArgumentError('Unsupported or invalid type: ' + type);
}