Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions eip712_structs/struct.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ def data_dict(self):
for k, v in self.values.items():
if isinstance(v, EIP712Struct):
result[k] = v.data_dict()
elif isinstance(v, list) and len(v) and isinstance(v[0], EIP712Struct):
result[k] = [ e.data_dict() for e in v ]
else:
result[k] = v
return result
Expand All @@ -94,7 +96,7 @@ def _encode_type(cls, resolve_references: bool) -> str:
struct_sig = f'{cls.type_name}({",".join(member_sigs)})'

if resolve_references:
reference_structs = set()
reference_structs = list()
cls._gather_reference_structs(reference_structs)
sorted_structs = sorted(list(s for s in reference_structs if s != cls), key=lambda s: s.type_name)
for struct in sorted_structs:
Expand All @@ -105,10 +107,16 @@ def _encode_type(cls, resolve_references: bool) -> str:
def _gather_reference_structs(cls, struct_set):
"""Finds reference structs defined in this struct type, and inserts them into the given set.
"""
structs = [m[1] for m in cls.get_members() if isinstance(m[1], type) and issubclass(m[1], EIP712Struct)]
structs = [
m[1] for m in cls.get_members()
if isinstance(m[1], type) and issubclass(m[1], EIP712Struct)
] + [
m[1].member_type for m in cls.get_members()
if isinstance(m[1], Array) and hasattr(m[1].member_type, "encode_type")
]
for struct in structs:
if struct not in struct_set:
struct_set.add(struct)
struct_set.append(struct)
struct._gather_reference_structs(struct_set)

@classmethod
Expand Down Expand Up @@ -162,7 +170,7 @@ def to_message(self, domain: 'EIP712Struct' = None) -> dict:
:returns: This struct + the domain in dict form, structured as specified for EIP712 messages.
"""
domain = self._assert_domain(domain)
structs = {domain, self}
structs = [domain, self]
self._gather_reference_structs(structs)

# Build type dictionary
Expand Down
5 changes: 4 additions & 1 deletion eip712_structs/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,10 @@ def __init__(self, member_type: Union[EIP712Type, Type[EIP712Type]], fixed_lengt
def _encode_value(self, value):
"""Arrays are encoded by concatenating their encoded contents, and taking the keccak256 hash."""
encoder = self.member_type
encoded_values = [encoder.encode_value(v) for v in value]
if hasattr(encoder, "hash_struct"):
encoded_values = [v.hash_struct() for v in value]
else:
encoded_values = [encoder.encode_value(v) for v in value]
return keccak(b''.join(encoded_values))


Expand Down