Skip to content

Commit

Permalink
fix: topics
Browse files Browse the repository at this point in the history
  • Loading branch information
antazoey committed Feb 14, 2025
1 parent d6a0810 commit 66bbedd
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 19 deletions.
48 changes: 33 additions & 15 deletions ethpm_types/abi.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
from typing import TYPE_CHECKING, Any, Literal, Optional, Union

from eth_pydantic_types import HexBytes
from eth_utils import keccak, to_hex
from eth_abi import grammar
from eth_abi.abi import encode
from eth_abi.packed import encode_packed
from eth_pydantic_types import HashStr32, HexBytes
from eth_utils import encode_hex, keccak, to_hex
from pydantic import ConfigDict, Field

from ethpm_types.base import BaseModel
Expand Down Expand Up @@ -357,28 +360,43 @@ def encode_topics(self, inputs: dict[str, Any]) -> list[Optional[str]]:
Returns:
list[Optional[str]]: Encoded topics.
"""
result: list[Optional[str]] = [str(to_hex(HexBytes(keccak(text=self.selector))))]
topics: list[Optional[str]] = [str(to_hex(HexBytes(keccak(text=self.selector))))]
for ipt in self.inputs:
if not ipt.indexed:
continue

name = getattr(ipt, "name", str(ipt))
if name and name in inputs:
input_value = inputs[name]
if isinstance(input_value, str) and input_value.startswith("0x"):
keccak_val = keccak(hexstr=inputs[name])
elif isinstance(input_value, str):
keccak_val = keccak(text=inputs[name])
else:
keccak_val = keccak(HexBytes(inputs[name]))

encoded_topic = to_hex(keccak_val)
result.append(encoded_topic)
topic = HashStr32.__eth_pydantic_validate__(inputs[name])
topics.append(topic)
else:
# Wildcard.
result.append(None)
topics.append(None)

return result
return topics


def encode_topic_value(abi_type, value):
"""
Encode a single topic.
Args:
abi_type (str): The ABI type of the topic.
value (Any): The value to encode.
Returns:
str: a hex-str of th encoded topic value.
"""
if isinstance(value, (list, tuple)):
return [encode_topic_value(abi_type, v) for v in value]

elif is_dynamic_sized_type(abi_type):
return encode_hex(keccak(encode_packed([str(abi_type)], [value])))

return encode_hex(encode([abi_type], [value]))


def is_dynamic_sized_type(abi_type: Union[ABIType, str]) -> bool:
parsed = grammar.parse(str(abi_type))
return parsed.is_dynamic


class ErrorABI(BaseABI):
Expand Down
8 changes: 4 additions & 4 deletions tests/test_abi.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,8 +164,8 @@ def test_encode_topics(self):
actual = event.encode_topics(topics)
expected = [
"0x36a46ac9279f9cc24a2b0ce490d205f822f91eb09330ba01a04d4b20577e469c",
"0xb710f78c797e0b10f6190e15ea85cdefebe41f2e61cfb696e173be39d6eab5a5",
"0xb710f78c797e0b10f6190e15ea85cdefebe41f2e61cfb696e173be39d6eab5a5",
"0x000000000000000000000000c627dafb1c8c8f28fbbb560ff4d3c85f602d4a69",
"0x000000000000000000000000c627dafb1c8c8f28fbbb560ff4d3c85f602d4a69",
]
assert actual == expected

Expand All @@ -176,7 +176,7 @@ def test_encode_topics_single_input(self):
actual = event.encode_topics(topics)
expected = [
"0x36a46ac9279f9cc24a2b0ce490d205f822f91eb09330ba01a04d4b20577e469c",
"0xb710f78c797e0b10f6190e15ea85cdefebe41f2e61cfb696e173be39d6eab5a5",
"0x000000000000000000000000c627dafb1c8c8f28fbbb560ff4d3c85f602d4a69",
None,
]
assert actual == expected
Expand All @@ -199,7 +199,7 @@ def test_encode_topics_int(self):
actual = event.encode_topics({"value": 1})
expected = [
"0xdfe7b17d34477d236495b6b3e918bcf8a53ae88d483b608ed1daf09f5424b4eb",
"0x5fe7f977e71dba2ea1a68e21057beebb9be2ac30c6410aa38d4f3fbe41dcffd2",
"0x0000000000000000000000000000000000000000000000000000000000000001",
]
assert actual == expected

Expand Down

0 comments on commit 66bbedd

Please sign in to comment.