Packages

Ethereum library for Gleam - JSON-RPC client, transaction signing, ABI encoding, and wallet management on the BEAM

Current section

Files

Jump to
gleeth src gleeth@ethereum@abi@types.erl
Raw

src/gleeth@ethereum@abi@types.erl

-module(gleeth@ethereum@abi@types).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/gleeth/ethereum/abi/types.gleam").
-export([is_dynamic/1, head_size/1, to_string/1]).
-export_type([abi_type/0, abi_value/0, abi_error/0]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
?MODULEDOC(
" Solidity ABI type system for encoding and decoding.\n"
"\n"
" `AbiType` describes the shape of a value (e.g. `Uint(256)`, `Address`,\n"
" `Array(Bool)`). `AbiValue` carries an actual value of that shape. Use\n"
" these with `abi/encode` and `abi/decode` to produce and consume raw\n"
" calldata.\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" // Describe a transfer(address, uint256) signature\n"
" let types = [Address, Uint(256)]\n"
"\n"
" // Construct the values\n"
" let values = [\n"
" AddressValue(\"0x70997970C51812dc3A010C7d01b50e0d17dc79C8\"),\n"
" UintValue(1000000),\n"
" ]\n"
" ```\n"
).
-type abi_type() :: {uint, integer()} |
{int, integer()} |
address |
bool |
{fixed_bytes, integer()} |
bytes |
string |
{array, abi_type()} |
{fixed_array, abi_type(), integer()} |
{tuple, list(abi_type())}.
-type abi_value() :: {uint_value, integer()} |
{int_value, integer()} |
{address_value, binary()} |
{bool_value, boolean()} |
{fixed_bytes_value, bitstring()} |
{bytes_value, bitstring()} |
{string_value, binary()} |
{array_value, list(abi_value())} |
{tuple_value, list(abi_value())}.
-type abi_error() :: {type_parse_error, binary()} |
{encode_error, binary()} |
{decode_error, binary()} |
{invalid_abi_json, binary()}.
-file("src/gleeth/ethereum/abi/types.gleam", 91).
?DOC(
" Returns `True` if the type uses dynamic (offset-based) ABI encoding.\n"
"\n"
" Static types (`uint`, `int`, `address`, `bool`, `bytesN`) are encoded\n"
" inline. Dynamic types (`bytes`, `string`, `T[]`) use a 32-byte offset\n"
" pointer in the head region.\n"
).
-spec is_dynamic(abi_type()) -> boolean().
is_dynamic(T) ->
case T of
{uint, _} ->
false;
{int, _} ->
false;
address ->
false;
bool ->
false;
{fixed_bytes, _} ->
false;
bytes ->
true;
string ->
true;
{array, _} ->
true;
{fixed_array, Element, _} ->
is_dynamic(Element);
{tuple, Elements} ->
gleam@list:any(Elements, fun is_dynamic/1)
end.
-file("src/gleeth/ethereum/abi/types.gleam", 112).
?DOC(" Fixed encoding size for static types.\n").
-spec enc_size(abi_type()) -> integer().
enc_size(T) ->
case T of
{uint, _} ->
32;
{int, _} ->
32;
address ->
32;
bool ->
32;
{fixed_bytes, _} ->
32;
{fixed_array, Element, Size} ->
Size * enc_size(Element);
{tuple, Elements} ->
gleam@list:fold(Elements, 0, fun(Acc, El) -> Acc + enc_size(El) end);
_ ->
32
end.
-file("src/gleeth/ethereum/abi/types.gleam", 104).
?DOC(
" Number of bytes this type occupies in the head region of a tuple encoding.\n"
" Static types are encoded inline (possibly > 32 bytes for arrays/tuples).\n"
" Dynamic types get a 32-byte offset pointer.\n"
).
-spec head_size(abi_type()) -> integer().
head_size(T) ->
case is_dynamic(T) of
true ->
32;
false ->
enc_size(T)
end.
-file("src/gleeth/ethereum/abi/types.gleam", 137).
?DOC(
" Canonical ABI type string used for function signatures and selectors.\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" types.to_string(Uint(256))\n"
" // -> \"uint256\"\n"
"\n"
" types.to_string(Array(Address))\n"
" // -> \"address[]\"\n"
"\n"
" types.to_string(Tuple([Address, Uint(256)]))\n"
" // -> \"(address,uint256)\"\n"
" ```\n"
).
-spec to_string(abi_type()) -> binary().
to_string(T) ->
case T of
{uint, Size} ->
<<"uint"/utf8, (erlang:integer_to_binary(Size))/binary>>;
{int, Size@1} ->
<<"int"/utf8, (erlang:integer_to_binary(Size@1))/binary>>;
address ->
<<"address"/utf8>>;
bool ->
<<"bool"/utf8>>;
{fixed_bytes, Size@2} ->
<<"bytes"/utf8, (erlang:integer_to_binary(Size@2))/binary>>;
bytes ->
<<"bytes"/utf8>>;
string ->
<<"string"/utf8>>;
{array, Element} ->
<<(to_string(Element))/binary, "[]"/utf8>>;
{fixed_array, Element@1, Size@3} ->
<<<<<<(to_string(Element@1))/binary, "["/utf8>>/binary,
(erlang:integer_to_binary(Size@3))/binary>>/binary,
"]"/utf8>>;
{tuple, Elements} ->
<<<<"("/utf8,
(gleam@string:join(
gleam@list:map(Elements, fun to_string/1),
<<","/utf8>>
))/binary>>/binary,
")"/utf8>>
end.