ABI (abi v0.1.21)

Documentation for ABI, the function interface language for Solidity. Generally, the ABI describes how to take binary Ethereum and transform it to or from types that Solidity understands.

Summary

Functions

Decodes the given data based on the function or tuple signature.

Encodes the given data into the function signature or tuple signature.

Parses the given ABI specification document into an array of ABI.FunctionSelectors.

Functions

Link to this function

decode(function_signature, data)

Decodes the given data based on the function or tuple signature.

In place of a signature, you can also pass one of the ABI.FunctionSelector structs returned from parse_specification/1.

Examples

iex> ABI.decode("baz(uint,address)", "00000000000000000000000000000000000000000000000000000000000000320000000000000000000000000000000000000000000000000000000000000001" |> Base.decode16!(case: :lower))
[50, <<1::160>>]

iex> ABI.decode("(address[])", "00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000" |> Base.decode16!(case: :lower))
[[]]

iex> ABI.decode("(uint256)", "000000000000000000000000000000000000000000000000000000000000000a" |> Base.decode16!(case: :lower))
[10]

iex> ABI.decode("(string)", "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000b457468657220546f6b656e000000000000000000000000000000000000000000" |> Base.decode16!(case: :lower))
["Ether Token"]

iex> File.read!("priv/dog.abi.json")
...> |> Jason.decode!
...> |> ABI.parse_specification
...> |> Enum.find(&(&1.function == "bark")) # bark(address,bool)
...> |> ABI.decode("00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001" |> Base.decode16!(case: :lower))
[<<1::160>>, true]
Link to this function

encode(function_signature, data)

Encodes the given data into the function signature or tuple signature.

In place of a signature, you can also pass one of the ABI.FunctionSelector structs returned from parse_specification/1.

Examples

iex> ABI.encode("(uint256)", [{10}])
...> |> Base.encode16(case: :lower)
"000000000000000000000000000000000000000000000000000000000000000a"

iex> ABI.encode("baz(uint,address)", [50, <<1::160>> |> :binary.decode_unsigned])
...> |> Base.encode16(case: :lower)
"a291add600000000000000000000000000000000000000000000000000000000000000320000000000000000000000000000000000000000000000000000000000000001"

iex> ABI.encode("price(string)", ["BAT"])
...> |> Base.encode16(case: :lower)
"fe2c6198000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000034241540000000000000000000000000000000000000000000000000000000000"

iex> ABI.encode("baz(uint8)", [9999])
** (RuntimeError) Data overflow encoding uint, data `9999` cannot fit in 8 bits

iex> ABI.encode("(uint,address)", [{50, <<1::160>> |> :binary.decode_unsigned}])
...> |> Base.encode16(case: :lower)
"00000000000000000000000000000000000000000000000000000000000000320000000000000000000000000000000000000000000000000000000000000001"

iex> ABI.encode("(string)", [{"Ether Token"}])
...> |> Base.encode16(case: :lower)
"0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000b457468657220546f6b656e000000000000000000000000000000000000000000"

iex> ABI.encode("(string)", [{String.duplicate("1234567890", 10)}])
...> |> Base.encode16(case: :lower)
"000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000643132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393000000000000000000000000000000000000000000000000000000000"

iex> File.read!("priv/dog.abi.json")
...> |> Jason.decode!
...> |> ABI.parse_specification
...> |> Enum.find(&(&1.function == "bark")) # bark(address,bool)
...> |> ABI.encode([<<1::160>> |> :binary.decode_unsigned, true])
...> |> Base.encode16(case: :lower)
"b85d0bd200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001"
Link to this function

parse_specification(doc)

Parses the given ABI specification document into an array of ABI.FunctionSelectors.

Non-function entries (e.g. constructors) in the ABI specification are skipped. Fallback function entries are accepted.

This function can be used in combination with a JSON parser, e.g. Jason, to parse ABI specification JSON files.

Examples

iex> File.read!("priv/dog.abi.json")
...> |> Jason.decode!
...> |> ABI.parse_specification
[%ABI.FunctionSelector{function: "bark", returns: nil, types: [:address, :bool], names: ["at", "loudly"]},
 %ABI.FunctionSelector{function: "rollover", returns: :bool, types: [], names: []}]

iex> [%{
...>   "constant" => true,
...>   "inputs" => [
...>     %{"name" => "at", "type" => "address"},
...>     %{"name" => "loudly", "type" => "bool"}
...>   ],
...>   "name" => "bark",
...>   "outputs" => [],
...>   "payable" => false,
...>   "stateMutability" => "nonpayable",
...>   "type" => "function"
...> }]
...> |> ABI.parse_specification
[%ABI.FunctionSelector{function: "bark", returns: nil, types: [:address, :bool], names: ["at", "loudly"]}]

iex> [%{
...>   "inputs" => [
...>      %{"name" => "_numProposals", "type" => "uint8"}
...>   ],
...>   "payable" => false,
...>   "stateMutability" => "nonpayable",
...>   "type" => "constructor"
...> }]
...> |> ABI.parse_specification
[]

iex> ABI.decode("(string)", "000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000643132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393000000000000000000000000000000000000000000000000000000000" |> Base.decode16!(case: :lower))
[String.duplicate("1234567890", 10)]

iex> [%{
...>   "payable" => false,
...>   "stateMutability" => "nonpayable",
...>   "type" => "fallback"
...> }]
...> |> ABI.parse_specification
[%ABI.FunctionSelector{function: nil, returns: nil, types: [], names: []}]