encodeData static method
Implementation
static Uint8List encodeData(String primaryType, dynamic data,
Map<String, List<TypedDataField>> types, String version) {
if (!(data is Map<String, dynamic>) && !(data is EIP712Domain))
throw ArgumentError("Unsupported data type");
final encodedTypes = <String>['bytes32'];
List<dynamic> encodedValues = [];
encodedValues.add(hashType(primaryType, types));
if (version == 'V4') {
List<dynamic> encodeField(String name, String type, dynamic value) {
if (types[type] != null) {
return [
'bytes32',
value == null // eslint-disable-line no-eq-null
? '0x0000000000000000000000000000000000000000000000000000000000000000'
: getKeccakDigest((encodeData(type, value, types, version)))
];
}
if (value == null)
throw ArgumentError(
'missing value for field ${name} of type ${type}');
if (type == 'bytes') {
if (value is String) {
if (isHexString(value)) {
value = getKeccakDigest(dynamicToUint8List(value));
} else {
value = getKeccakDigest(Uint8List.fromList(utf8.encode(value)));
}
} else if (value is List) {
value = getKeccakDigest(Uint8List.fromList(List<int>.from(value)));
} else {
throw new ArgumentError('Not supported type for bytes');
}
return ['bytes32', value];
}
if (type == 'string') {
// convert string to buffer - prevents ethUtil from interpreting strings like '0xabcd' as hex
if (value is String) value = Uint8List.fromList(utf8.encode(value));
return ['bytes32', getKeccakDigest(value)];
}
if (type.lastIndexOf(']') == type.length - 1) {
final parsedType = type.substring(0, type.lastIndexOf('['));
final typeValuePairs =
value.map((item) => encodeField(name, parsedType, item)).toList();
final List<String> tList =
(typeValuePairs as List).map((l) => l[0].toString()).toList();
final List<dynamic> vList = typeValuePairs.map((l) => l[1]).toList();
return [
'bytes32',
getKeccakDigest(
AbiUtil.rawEncode(
tList,
vList,
),
),
];
}
return [type, value];
}
final fields = types[primaryType];
fields?.forEach((field) {
final List<dynamic> result = encodeField(
field.name,
field.type,
data[field.name],
);
encodedTypes.add(result[0]);
encodedValues.add(result[1]);
});
} else {
types[primaryType]?.forEach((TypedDataField field) {
var value = data[field.name];
if (value != null) {
if (field.type == 'bytes') {
encodedTypes.add('bytes32');
if (value is String) {
if (isHexString(value)) {
value = getKeccakDigest(dynamicToUint8List(value));
} else {
value = getKeccakDigest(Uint8List.fromList(utf8.encode(value)));
}
}
encodedValues.add(value);
} else if (field.type == 'string') {
encodedTypes.add('bytes32');
// convert string to buffer - prevents ethUtil from interpreting strings like '0xabcd' as hex
if (value is String) {
value = Uint8List.fromList(utf8.encode(value));
}
value = getKeccakDigest(value);
encodedValues.add(value);
} else if (types[field.type] != null) {
encodedTypes.add('bytes32');
value =
getKeccakDigest(encodeData(field.type, value, types, version));
encodedValues.add(value);
} else if (field.type.lastIndexOf(']') == field.type.length - 1) {
throw new ArgumentError(
'Arrays are unimplemented in encodeData; use V4 extension');
} else {
encodedTypes.add(field.type);
encodedValues.add(value);
}
}
});
}
return AbiUtil.rawEncode(encodedTypes, encodedValues);
}