`encodeData` doesn't support array types
Currently a placeholder error is thrown when abi encoding an array type. This should be replaced with a genuine implementation of the ABI encoding for arrays
I'm just trying to figure this out. In EIP712 specification it is stated: The array values are encoded as the keccak256 hash of the concatenated encodeData of their contents (i.e. the encoding of SomeType[5] is identical to that of a struct containing five members of type SomeType). From this I figure it should be something like:
if (field.type == 'array') {
for (let v of value) {
encTypes.push('bytes32');
value = ethUtil.keccak256(encodeData(field.items.type, v))
encValues.push(value);
}
}
@Alko89 That only applies for fixed-length arrays, not for arrays of arbitrary length.
In that case, the encoded hash of the array would be a single bytes32 that is just the keccak256 of: the encoded values of each element in the array in 32-byte chunks
I have created a pull request where you can see an implementation that addresses this issue. To answer the question above, I will point out that:
-
encodeData(), which in this library always operates in the context of a struct, encodes each of the fields in the struct and returns the concatenation of the results. - The encoding for a field that is a struct is the hash of the
encodeData()for the struct. - The encoding for a field that is an array is the hash of the concatenation of the field encodings of each element of the array.
So: encodeData() for a field in a struct does the same thing as the field encoding for an array: take the hash of the concatenation of the field encodings of each sub-element.
Some examples:
- For an array of atomic types, the array encoding will be the hash of the concatenation of the raw encoding of each element.
- For an array of structs, the array encoding will be the hash of the concatenation of the encoding of each element, and since the elements are structs, the encoding of each element is a hash of the concatenation of the encodings of each of the members of the struct.
Since there are no good Solidity examples of this out there either, I'll point out that implementing this in Solidity is pretty straightforward: construct an array arr of all of the encodings of the elements, and then the struct hash of the array is keccak256(abi.encodePacked(arr)).
One other note, since the spec is worded somewhat confusingly and is structured slightly differently than the code here. The encodeData() for a struct, as implemented here, includes the type hash. The encoding for an array field does not include a type hash.
In the spec, the inclusion of the type hash is part of the definition of hashStruct() rather than encodeData(). The end result is the same.