Skip to content

Commit 0ece2e8

Browse files
Fix event selector matching (#157)
* fix: event selector matching * fix: update method_id type
1 parent 36d4e62 commit 0ece2e8

File tree

4 files changed

+47
-26
lines changed

4 files changed

+47
-26
lines changed

lib/abi.ex

+1-1
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ defmodule ABI do
212212
...> |> Jason.decode!
213213
...> |> ABI.parse_specification(include_events?: true)
214214
...> |> Enum.filter(&(&1.type == :event))
215-
[%ABI.FunctionSelector{type: :event, function: "WantsPets", input_names: ["_from_human", "_number", "_belly"], inputs_indexed: [true, false, true], method_id: <<235, 155, 60, 76>>, types: [:string, {:uint, 256}, :bool]}]
215+
[%ABI.FunctionSelector{type: :event, function: "WantsPets", input_names: ["_from_human", "_number", "_belly"], inputs_indexed: [true, false, true], method_id: <<235, 155, 60, 76, 236, 41, 90, 133, 158, 131, 71, 199, 88, 206, 85, 83, 36, 105, 140, 112, 231, 125, 249, 63, 87, 99, 121, 242, 184, 82, 161, 19>>, types: [:string, {:uint, 256}, :bool]}]
216216
217217
iex> File.read!("priv/example1.abi.json")
218218
...> |> Jason.decode!

lib/abi/event.ex

+3-4
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ defmodule ABI.Event do
5454
function: "WantsPets",
5555
input_names: ["_from_human", "_number", "_belly"],
5656
inputs_indexed: [true, false, true],
57-
method_id: <<235, 155, 60, 76>>,
57+
method_id: <<235, 155, 60, 76, 236, 41, 90, 133, 158, 131, 71, 199, 88, 206, 85, 83, 36, 105, 140, 112, 231, 125, 249, 63, 87, 99, 121, 242, 184, 82, 161, 19>>,
5858
types: [:string, {:uint, 256}, :bool]
5959
},
6060
[
@@ -69,9 +69,8 @@ defmodule ABI.Event do
6969
def find_and_decode(function_selectors, topic1, topic2, topic3, topic4, data) do
7070
input_topics = [topic2, topic3, topic4]
7171

72-
with {:ok, method_id, _rest} <- Util.split_method_id(topic1),
73-
{:ok, selector} when not is_nil(selector) <-
74-
Util.find_selector_by_event_id(function_selectors, method_id, input_topics) do
72+
with {:ok, selector} when not is_nil(selector) <-
73+
Util.find_selector_by_event_id(function_selectors, topic1, input_topics) do
7574
args = Enum.zip([selector.input_names, selector.types, selector.inputs_indexed])
7675

7776
{indexed_args, unindexed_args} =

lib/abi/function_selector.ex

+9-3
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,14 @@ defmodule ABI.FunctionSelector do
2929
* `:types` - Function's input types
3030
* `:returns` - Function's return types
3131
* `:return_names` - Names of the return values (output names)
32-
* `:method_id` - First four bits of the hashed function signature
32+
* `:method_id` - First four bytes of the hashed function signature or full 32 byte hash for events
3333
* `:input_names` - Names of the input values (argument names)
3434
* `:type` - The type of the selector. Events are part of the ABI, but are not considered functions
3535
* `:inputs_index` - A list of true/false values denoting if each input is indexed. Only populated for events.
3636
"""
3737
@type t :: %__MODULE__{
3838
function: String.t() | nil,
39-
method_id: String.t() | nil,
39+
method_id: binary | nil,
4040
input_names: [String.t()],
4141
types: [type],
4242
returns: [type],
@@ -260,7 +260,7 @@ defmodule ABI.FunctionSelector do
260260
type: :event
261261
}
262262

263-
add_method_id(selector)
263+
add_event_id(selector)
264264
else
265265
_ -> nil
266266
end
@@ -415,6 +415,12 @@ defmodule ABI.FunctionSelector do
415415
end
416416
end
417417

418+
defp add_event_id(selector) do
419+
signature = encode(selector)
420+
421+
%{selector | method_id: ExKeccak.hash_256(signature)}
422+
end
423+
418424
defp get_types(function_selector) do
419425
for type <- function_selector.types do
420426
get_type(type)

test/abi/util_test.exs

+34-18
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ defmodule ABI.UtilTest do
44
@selectors [
55
%ABI.FunctionSelector{
66
function: "Transfer",
7-
method_id: <<221, 242, 82, 173>>,
7+
method_id:
8+
<<221, 242, 82, 173, 27, 226, 200, 155, 105, 194, 176, 104, 252, 55, 141, 170, 149, 43,
9+
167, 241, 99, 196, 161, 22, 40, 245, 90, 77, 245, 35, 179, 239>>,
810
type: :event,
911
inputs_indexed: [false, false, false],
1012
state_mutability: nil,
@@ -14,7 +16,9 @@ defmodule ABI.UtilTest do
1416
},
1517
%ABI.FunctionSelector{
1618
function: "Transfer",
17-
method_id: <<221, 242, 82, 173>>,
19+
method_id:
20+
<<221, 242, 82, 173, 27, 226, 200, 155, 105, 194, 176, 104, 252, 55, 141, 170, 149, 43,
21+
167, 241, 99, 196, 161, 22, 40, 245, 90, 77, 245, 35, 179, 239>>,
1822
type: :event,
1923
inputs_indexed: [true, true, true],
2024
state_mutability: nil,
@@ -24,7 +28,9 @@ defmodule ABI.UtilTest do
2428
},
2529
%ABI.FunctionSelector{
2630
function: "OwnershipTransferred",
27-
method_id: <<139, 224, 7, 156>>,
31+
method_id:
32+
<<139, 224, 7, 156, 83, 22, 89, 20, 19, 68, 205, 31, 208, 164, 242, 132, 25, 73, 127, 151,
33+
34, 163, 218, 175, 227, 180, 24, 111, 107, 100, 87, 224>>,
2834
type: :event,
2935
inputs_indexed: [true, true],
3036
state_mutability: nil,
@@ -37,28 +43,38 @@ defmodule ABI.UtilTest do
3743
describe "decode events" do
3844
test "successfully decodes ERC721 transfer event" do
3945
{:ok, selector} =
40-
ABI.Util.find_selector_by_event_id(@selectors, <<221, 242, 82, 173>>, [
41-
<<0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 218, 29, 25, 253, 206, 193, 121, 186, 151,
42-
85, 242, 198, 19, 159, 143, 254, 203, 254, 176>>,
43-
<<0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 168, 47, 182, 247, 249, 220, 207, 188, 171, 157,
44-
153, 173, 222, 184, 132, 3, 58, 241, 27, 134>>,
45-
<<0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
46-
0, 12, 12>>
47-
])
46+
ABI.Util.find_selector_by_event_id(
47+
@selectors,
48+
<<221, 242, 82, 173, 27, 226, 200, 155, 105, 194, 176, 104, 252, 55, 141, 170, 149, 43,
49+
167, 241, 99, 196, 161, 22, 40, 245, 90, 77, 245, 35, 179, 239>>,
50+
[
51+
<<0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 218, 29, 25, 253, 206, 193, 121, 186, 151,
52+
85, 242, 198, 19, 159, 143, 254, 203, 254, 176>>,
53+
<<0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 168, 47, 182, 247, 249, 220, 207, 188, 171, 157,
54+
153, 173, 222, 184, 132, 3, 58, 241, 27, 134>>,
55+
<<0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
56+
0, 0, 12, 12>>
57+
]
58+
)
4859

4960
assert selector.function == "Transfer"
5061
assert selector.inputs_indexed == [true, true, true]
5162
end
5263

5364
test "decode OwnershipTransferred event" do
5465
{:ok, selector} =
55-
ABI.Util.find_selector_by_event_id(@selectors, <<139, 224, 7, 156>>, [
56-
<<0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
57-
0, 0, 0>>,
58-
<<0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, 181, 74, 58, 157, 2, 63, 219, 87, 69, 216,
59-
158, 228, 106, 170, 82, 18, 171, 87, 125>>,
60-
nil
61-
])
66+
ABI.Util.find_selector_by_event_id(
67+
@selectors,
68+
<<139, 224, 7, 156, 83, 22, 89, 20, 19, 68, 205, 31, 208, 164, 242, 132, 25, 73, 127,
69+
151, 34, 163, 218, 175, 227, 180, 24, 111, 107, 100, 87, 224>>,
70+
[
71+
<<0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
72+
0, 0, 0, 0>>,
73+
<<0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, 181, 74, 58, 157, 2, 63, 219, 87, 69, 216,
74+
158, 228, 106, 170, 82, 18, 171, 87, 125>>,
75+
nil
76+
]
77+
)
6278

6379
assert selector.function == "OwnershipTransferred"
6480
assert selector.inputs_indexed == [true, true]

0 commit comments

Comments
 (0)