Fix event selector matching (#157)

* fix: event selector matching

* fix: update method_id type
This commit is contained in:
Kirill Fedoseev 2024-01-31 14:54:21 +04:00 committed by GitHub
parent 36d4e62694
commit 0ece2e8fa7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 47 additions and 26 deletions

View File

@ -212,7 +212,7 @@ defmodule ABI do
...> |> Jason.decode!
...> |> ABI.parse_specification(include_events?: true)
...> |> Enum.filter(&(&1.type == :event))
[%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]}]
[%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]}]
iex> File.read!("priv/example1.abi.json")
...> |> Jason.decode!

View File

@ -54,7 +54,7 @@ defmodule ABI.Event do
function: "WantsPets",
input_names: ["_from_human", "_number", "_belly"],
inputs_indexed: [true, false, true],
method_id: <<235, 155, 60, 76>>,
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]
},
[
@ -69,9 +69,8 @@ defmodule ABI.Event do
def find_and_decode(function_selectors, topic1, topic2, topic3, topic4, data) do
input_topics = [topic2, topic3, topic4]
with {:ok, method_id, _rest} <- Util.split_method_id(topic1),
{:ok, selector} when not is_nil(selector) <-
Util.find_selector_by_event_id(function_selectors, method_id, input_topics) do
with {:ok, selector} when not is_nil(selector) <-
Util.find_selector_by_event_id(function_selectors, topic1, input_topics) do
args = Enum.zip([selector.input_names, selector.types, selector.inputs_indexed])
{indexed_args, unindexed_args} =

View File

@ -29,14 +29,14 @@ defmodule ABI.FunctionSelector do
* `:types` - Function's input types
* `:returns` - Function's return types
* `:return_names` - Names of the return values (output names)
* `:method_id` - First four bits of the hashed function signature
* `:method_id` - First four bytes of the hashed function signature or full 32 byte hash for events
* `:input_names` - Names of the input values (argument names)
* `:type` - The type of the selector. Events are part of the ABI, but are not considered functions
* `:inputs_index` - A list of true/false values denoting if each input is indexed. Only populated for events.
"""
@type t :: %__MODULE__{
function: String.t() | nil,
method_id: String.t() | nil,
method_id: binary | nil,
input_names: [String.t()],
types: [type],
returns: [type],
@ -260,7 +260,7 @@ defmodule ABI.FunctionSelector do
type: :event
}
add_method_id(selector)
add_event_id(selector)
else
_ -> nil
end
@ -415,6 +415,12 @@ defmodule ABI.FunctionSelector do
end
end
defp add_event_id(selector) do
signature = encode(selector)
%{selector | method_id: ExKeccak.hash_256(signature)}
end
defp get_types(function_selector) do
for type <- function_selector.types do
get_type(type)

View File

@ -4,7 +4,9 @@ defmodule ABI.UtilTest do
@selectors [
%ABI.FunctionSelector{
function: "Transfer",
method_id: <<221, 242, 82, 173>>,
method_id:
<<221, 242, 82, 173, 27, 226, 200, 155, 105, 194, 176, 104, 252, 55, 141, 170, 149, 43,
167, 241, 99, 196, 161, 22, 40, 245, 90, 77, 245, 35, 179, 239>>,
type: :event,
inputs_indexed: [false, false, false],
state_mutability: nil,
@ -14,7 +16,9 @@ defmodule ABI.UtilTest do
},
%ABI.FunctionSelector{
function: "Transfer",
method_id: <<221, 242, 82, 173>>,
method_id:
<<221, 242, 82, 173, 27, 226, 200, 155, 105, 194, 176, 104, 252, 55, 141, 170, 149, 43,
167, 241, 99, 196, 161, 22, 40, 245, 90, 77, 245, 35, 179, 239>>,
type: :event,
inputs_indexed: [true, true, true],
state_mutability: nil,
@ -24,7 +28,9 @@ defmodule ABI.UtilTest do
},
%ABI.FunctionSelector{
function: "OwnershipTransferred",
method_id: <<139, 224, 7, 156>>,
method_id:
<<139, 224, 7, 156, 83, 22, 89, 20, 19, 68, 205, 31, 208, 164, 242, 132, 25, 73, 127, 151,
34, 163, 218, 175, 227, 180, 24, 111, 107, 100, 87, 224>>,
type: :event,
inputs_indexed: [true, true],
state_mutability: nil,
@ -37,14 +43,19 @@ defmodule ABI.UtilTest do
describe "decode events" do
test "successfully decodes ERC721 transfer event" do
{:ok, selector} =
ABI.Util.find_selector_by_event_id(@selectors, <<221, 242, 82, 173>>, [
<<0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 218, 29, 25, 253, 206, 193, 121, 186, 151,
85, 242, 198, 19, 159, 143, 254, 203, 254, 176>>,
<<0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 168, 47, 182, 247, 249, 220, 207, 188, 171, 157,
153, 173, 222, 184, 132, 3, 58, 241, 27, 134>>,
<<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,
0, 12, 12>>
])
ABI.Util.find_selector_by_event_id(
@selectors,
<<221, 242, 82, 173, 27, 226, 200, 155, 105, 194, 176, 104, 252, 55, 141, 170, 149, 43,
167, 241, 99, 196, 161, 22, 40, 245, 90, 77, 245, 35, 179, 239>>,
[
<<0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 218, 29, 25, 253, 206, 193, 121, 186, 151,
85, 242, 198, 19, 159, 143, 254, 203, 254, 176>>,
<<0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 168, 47, 182, 247, 249, 220, 207, 188, 171, 157,
153, 173, 222, 184, 132, 3, 58, 241, 27, 134>>,
<<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, 0, 12, 12>>
]
)
assert selector.function == "Transfer"
assert selector.inputs_indexed == [true, true, true]
@ -52,13 +63,18 @@ defmodule ABI.UtilTest do
test "decode OwnershipTransferred event" do
{:ok, selector} =
ABI.Util.find_selector_by_event_id(@selectors, <<139, 224, 7, 156>>, [
<<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,
0, 0, 0>>,
<<0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, 181, 74, 58, 157, 2, 63, 219, 87, 69, 216,
158, 228, 106, 170, 82, 18, 171, 87, 125>>,
nil
])
ABI.Util.find_selector_by_event_id(
@selectors,
<<139, 224, 7, 156, 83, 22, 89, 20, 19, 68, 205, 31, 208, 164, 242, 132, 25, 73, 127,
151, 34, 163, 218, 175, 227, 180, 24, 111, 107, 100, 87, 224>>,
[
<<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, 0, 0, 0>>,
<<0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, 181, 74, 58, 157, 2, 63, 219, 87, 69, 216,
158, 228, 106, 170, 82, 18, 171, 87, 125>>,
nil
]
)
assert selector.function == "OwnershipTransferred"
assert selector.inputs_indexed == [true, true]