ABI.FunctionSelector (abi v1.3.0)
Module to help parse the ABI function signatures, e.g.
my_function(uint64, string[])
.
Summary
Functions
Decodes a function selector to a struct.
Decodes the given type-string as a simple array of types.
Decodes the given type-string as a single type.
Encodes a function call signature. If indexed=true
, returns
the "indexed"
keyword after indexed parameters.
Parse a function selector, e.g. from an abi.json file.
Types
Link to this type
argument_type()
Link to this type
function_type()
@type function_type() ::
:function | :constructor | :fallback | :receive | :error | :event
Link to this type
state_mutability()
@type state_mutability() :: :nonpayable | :pure | :view | :payable
@type t() :: %ABI.FunctionSelector{ function: String.t(), function_type: function_type() | nil, returns: type(), state_mutability: state_mutability() | nil, types: [argument_type()] }
Link to this type
type()
@type type() :: {:uint, integer()} | :bool | :bytes | :string | :address | {:int, integer()} | {:array, type()} | {:array, type(), non_neg_integer()} | {:tuple, [argument_type()]}
Functions
Link to this function
decode(signature)
Decodes a function selector to a struct.
Examples
iex> ABI.FunctionSelector.decode("bark(uint256,bool)")
%ABI.FunctionSelector{
function: "bark",
types: [
%{type: {:uint, 256}},
%{type: :bool}
]
}
iex> ABI.FunctionSelector.decode("bark(uint256 name, bool loud)")
%ABI.FunctionSelector{
function: "bark",
types: [
%{type: {:uint, 256}, name: "name"},
%{type: :bool, name: "loud"}
]
}
iex> ABI.FunctionSelector.decode("bark(uint256 name,bool indexed loud)")
%ABI.FunctionSelector{
function: "bark",
types: [
%{type: {:uint, 256}, name: "name"},
%{type: :bool, name: "loud", indexed: true}
]
}
iex> ABI.FunctionSelector.decode("(uint256,bool)")
%ABI.FunctionSelector{
function: nil,
types: [
%{type: {:uint, 256}},
%{type: :bool}
]
}
iex> ABI.FunctionSelector.decode("growl(uint,address,string[])")
%ABI.FunctionSelector{
function: "growl",
types: [
%{type: {:uint, 256}},
%{type: :address},
%{type: {:array, :string}}
]
}
iex> ABI.FunctionSelector.decode("rollover()")
%ABI.FunctionSelector{
function: "rollover",
types: []
}
iex> ABI.FunctionSelector.decode("do_playDead3()")
%ABI.FunctionSelector{
function: "do_playDead3",
types: []
}
iex> ABI.FunctionSelector.decode("pet(address[])")
%ABI.FunctionSelector{
function: "pet",
types: [
%{type: {:array, :address}}
]
}
iex> ABI.FunctionSelector.decode("paw(string[2])")
%ABI.FunctionSelector{
function: "paw",
types: [
%{type: {:array, :string, 2}}
]
}
iex> ABI.FunctionSelector.decode("scram(uint256[])")
%ABI.FunctionSelector{
function: "scram",
types: [
%{type: {:array, {:uint, 256}}}
]
}
iex> ABI.FunctionSelector.decode("shake((string))")
%ABI.FunctionSelector{
function: "shake",
types: [
%{type: {:tuple, [%{type: :string}]}}
]
}
Link to this function
decode_raw(type_string)
Decodes the given type-string as a simple array of types.
Examples
iex> ABI.FunctionSelector.decode_raw("string,uint256")
[:string, {:uint, 256}]
iex> ABI.FunctionSelector.decode_raw("")
[]
Link to this function
decode_type(single_type)
Decodes the given type-string as a single type.
Examples
iex> ABI.FunctionSelector.decode_type("uint256")
{:uint, 256}
iex> ABI.FunctionSelector.decode_type("(bool,address)")
{:tuple, [%{type: :bool}, %{type: :address}]}
iex> ABI.FunctionSelector.decode_type("address[][3]")
{:array, {:array, :address}, 3}
Link to this function
encode(function_selector, indexed \\ false, names \\ false)
Encodes a function call signature. If indexed=true
, returns
the "indexed"
keyword after indexed parameters.
Example
iex> ABI.FunctionSelector.encode(%ABI.FunctionSelector{
...> function: "bark",
...> types: [
...> %{type: {:uint, 256}},
...> %{type: :bool, indexed: true},
...> %{type: {:array, :string}},
...> %{type: {:array, :string, 3}},
...> %{type: {:tuple, [%{type: {:uint, 256}}, %{type: :bool}]}}
...> ]
...> })
"bark(uint256,bool,string[],string[3],(uint256,bool))"
iex> ABI.FunctionSelector.encode(%ABI.FunctionSelector{
...> function: "bark",
...> types: [
...> %{type: {:uint, 256}},
...> %{type: :bool, indexed: true},
...> %{type: {:array, :string}},
...> %{type: {:array, :string, 3}},
...> %{type: {:tuple, [%{type: {:uint, 256}}, %{type: :bool}]}}
...> ]
...> }, true)
"bark(uint256,bool indexed,string[],string[3],(uint256,bool))"
iex> ABI.FunctionSelector.encode(%ABI.FunctionSelector{
...> function: "bark",
...> types: [
...> %{type: {:uint, 256}},
...> %{type: :bool, indexed: true},
...> %{type: {:array, :string}},
...> %{type: {:array, :string, 3}},
...> %{type: {:tuple, [%{type: {:uint, 256}}, %{type: :bool}]}}
...> ]
...> }, true, true)
"bark(uint256 var0,bool indexed var1,string[] var2,string[3] var3,(uint256,bool) var4)"
iex> ABI.FunctionSelector.encode(%ABI.FunctionSelector{
...> function: "bark",
...> types: [
...> %{type: {:uint, 256}},
...> %{type: :bool, indexed: true},
...> %{type: {:array, :string}},
...> %{type: {:array, :string, 3}},
...> %{type: {:tuple, [%{type: {:uint, 256}}, %{type: :bool}]}}
...> ]
...> }, false, true)
"bark(uint256 var0,bool var1,string[] var2,string[3] var3,(uint256,bool) var4)"
iex> ABI.FunctionSelector.encode(%ABI.FunctionSelector{
...> function: "bark",
...> types: [
...> %{type: {:uint, 256}, name: "a"},
...> %{type: :bool, indexed: true, name: "b"},
...> %{type: {:array, :string}, name: "c"},
...> %{type: {:array, :string, 3}, name: "d"},
...> %{type: {:tuple, [%{type: {:uint, 256}}, %{type: :bool}]}, name: "e"}
...> ]
...> }, false, true)
"bark(uint256 a,bool b,string[] c,string[3] d,(uint256,bool) e)"
Link to this function
parse_specification_item(item)
Parse a function selector, e.g. from an abi.json file.
Examples
iex> ABI.FunctionSelector.parse_specification_item(%{"type" => "function", "name" => "fun", "inputs" => [%{"name" => "a", "type" => "uint96", "internalType" => "uint96"}]})
%ABI.FunctionSelector{
function: "fun",
function_type: :function,
types: [%{type: {:uint, 96}, name: "a"}],
returns: nil
}
iex> ABI.FunctionSelector.parse_specification_item(%{"type" => "function", "name" => "fun", "inputs" => [%{"name" => "s", "type" => "tuple", "internalType" => "tuple", "components" => [%{"name" => "a", "type" => "uint256", "internalType" => "uint256"},%{"name" => "b", "type" => "address", "internalType" => "address"},%{"name" => "c", "type" => "bytes", "internalType" => "bytes"}]},%{"name" => "d", "type" => "uint256", "internalType" => "uint256"}],"outputs" => [%{"name" => "", "type" => "bytes", "internalType" => "bytes"}],"stateMutability" => "view"})
%ABI.FunctionSelector{
function: "fun",
function_type: :function,
state_mutability: :view,
types: [
%{
type:
{:tuple, [
%{type: {:uint, 256}, name: "a"},
%{type: :address, name: "b"},
%{type: :bytes, name: "c"}
]},
name: "s"
}, %{
type: {:uint, 256},
name: "d"
}
],
returns: [%{name: "", type: :bytes}],
}
iex> ABI.FunctionSelector.parse_specification_item(%{"type" => "function", "name" => "fun", "inputs" => [%{"name" => "s", "type" => "tuple", "internalType" => "struct Contract.Struct", "components" => [%{"name" => "a", "type" => "uint256", "internalType" => "uint256"},%{"name" => "b", "type" => "address", "internalType" => "address"},%{"name" => "c", "type" => "bytes", "internalType" => "bytes"}]},%{"name" => "d", "type" => "uint256", "internalType" => "uint256"}],"outputs" => [%{"name" => "", "type" => "bytes", "internalType" => "bytes"}],"stateMutability" => "pure"})
%ABI.FunctionSelector{
function: "fun",
function_type: :function,
state_mutability: :pure,
types: [
%{
type:
{:tuple, [
%{type: {:uint, 256}, name: "a"},
%{type: :address, name: "b"},
%{type: :bytes, name: "c"}
]},
name: "s"
}, %{
type: {:uint, 256},
name: "d"
}
],
returns: [%{name: "", type: :bytes}],
}
iex> ABI.FunctionSelector.parse_specification_item(%{"type" => "function", "name" => "fun", "inputs" => [%{"name" => "s", "type" => "tuple", "internalType" => "struct Contract.Struct", "components" => [%{"name" => "a", "type" => "uint256", "internalType" => "uint256"},%{"type" => "address", "internalType" => "address"},%{"name" => "c", "type" => "bytes", "internalType" => "bytes"}]},%{"name" => "d", "type" => "uint256", "internalType" => "uint256"}],"outputs" => [%{"name" => "", "type" => "bytes", "internalType" => "bytes"}],"stateMutability" => "payable"})
%ABI.FunctionSelector{
function: "fun",
function_type: :function,
state_mutability: :payable,
types: [
%{
type:
{:tuple, [
%{type: {:uint, 256}, name: "a"},
%{type: :address},
%{type: :bytes, name: "c"}
]},
name: "s"
}, %{
type: {:uint, 256},
name: "d"
}
],
returns: [%{name: "", type: :bytes}],
}
iex> ABI.FunctionSelector.parse_specification_item(%{"type" => "fallback"})
%ABI.FunctionSelector{
function: nil,
function_type: :fallback,
types: [],
returns: nil
}
iex> ABI.FunctionSelector.parse_specification_item(%{"type" => "receive"})
%ABI.FunctionSelector{
function: nil,
function_type: :receive,
types: [],
returns: nil
}
iex> ABI.FunctionSelector.parse_specification_item(%{"inputs" => [%{"internalType" => "address[]", "name" => "xs", "type" => "address[]"}, %{"internalType" => "bytes[]", "name" => "ys", "type" => "bytes[]"}, %{"components" => [%{"internalType" => "enum Z", "name" => "za", "type" => "uint8"}, %{"internalType" => "enum Z", "name" => "zb", "type" => "uint8"}], "internalType" => "struct Z.Z[]", "name" => "zs", "type" => "tuple[]"}, %{"internalType" => "bytes[]", "name" => "zz", "type" => "bytes[]"}], "name" => "go", "outputs" => [%{"internalType" => "bytes[]", "name" => "", "type" => "bytes[]"}], "stateMutability" => "nonpayable", "type" => "function"})
%ABI.FunctionSelector{
function: "go",
function_type: :function,
state_mutability: :nonpayable,
types: [
%{name: "xs", type: {:array, :address}},
%{name: "ys", type: {:array, :bytes}},
%{
name: "zs",
type:
{:array,
{:tuple,
[%{name: "za", type: {:uint, 8}}, %{name: "zb", type: {:uint, 8}}]}}
},
%{name: "zz", type: {:array, :bytes}}
],
returns: [%{name: "", type: {:array, :bytes}}]
}
iex> ABI.FunctionSelector.parse_specification_item(%{"anonymous" => false, "inputs" => [%{"indexed" => true, "internalType" => "address", "name" => "z0", "type" => "address"}, %{"indexed" => true, "internalType" => "address", "name" => "z1", "type" => "address"}, %{"indexed" => false, "internalType" => "address", "name" => "z2", "type" => "address"}, %{"indexed" => false, "internalType" => "bytes32", "name" => "z3", "type" => "bytes32"}], "name" => "z4", "type" => "event"})
%ABI.FunctionSelector{
function: "z4",
function_type: :event,
state_mutability: nil,
types: [
%{name: "z0", type: :address, indexed: true},
%{name: "z1", type: :address, indexed: true},
%{name: "z2", type: :address, indexed: false},
%{name: "z3", type: {:bytes, 32}, indexed: false}
],
returns: nil
}
iex> ABI.FunctionSelector.parse_specification_item(%{"inputs" => [], "name" => "Abc", "type" => "error"})
%ABI.FunctionSelector{function: "Abc", function_type: :error, state_mutability: nil, types: [], returns: nil}