Created
January 8, 2022 11:30
-
-
Save Nickforall/bdfd94ff47b2cddb8c1ece9e87374963 to your computer and use it in GitHub Desktop.
Call multicall contract with ExAbi in Elixir
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule MyProject.Ethereum.Multicall do | |
@multicall_addr "0xeefBa1e63905eF1D7ACbA5a8513c70307C1cE441" | |
@doc """ | |
Takes a list of {address, call} tuples, returns an ok tuple with block number and data in same order as list of calls | |
iex> MyProject.Ethereum.Multicall.multicall({"0x000", ABI.encode("tokenURI(uint256)", [token_id])}) | |
{:ok, 0x000} | |
""" | |
def multicall(list) do | |
abi_data = | |
list | |
|> Enum.map(&encode_call/1) | |
|> encode_aggregate_call() | |
Ethereumex.HttpClient.eth_call(%{ | |
data: "0x" <> abi_data, | |
to: @multicall_addr | |
}) | |
|> case do | |
{:ok, data} -> | |
data | |
|> String.slice(2..-1) | |
|> Base.decode16!(case: :lower) | |
|> ABI.TypeDecoder.decode_raw([{:uint, 256}, {:array, :bytes}]) | |
|> case do | |
[block_number, answers] -> {:ok, block_number, answers} | |
_ -> {:error, "Incorrectly formatted response from aggregate function"} | |
end | |
{:error, error} -> | |
{:error, error} | |
end | |
end | |
defp encode_call({"0x" <> address, data}) do | |
{Base.decode16!(address, case: :mixed), data} | |
end | |
defp encode_aggregate_call(calls) do | |
ABI.encode("aggregate((address,bytes)[])", [calls]) | |
|> Base.encode16(case: :lower) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment