encodeSingle static method
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);
}