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@contract.erl
Raw

src/gleeth@ethereum@contract.erl

-module(gleeth@ethereum@contract).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/gleeth/ethereum/contract.gleam").
-export([generate_function_selector/2, encode_parameters/1, build_call_data/2, parse_parameter/1]).
-file("src/gleeth/ethereum/contract.gleam", 88).
-spec parse_abi_type(binary()) -> {ok, gleeth@ethereum@abi@types:abi_type()} |
{error, gleeth@rpc@types:gleeth_error()}.
parse_abi_type(Type_str) ->
case string:lowercase(Type_str) of
<<"uint256"/utf8>> ->
{ok, {uint, 256}};
<<"uint"/utf8>> ->
{ok, {uint, 256}};
<<"address"/utf8>> ->
{ok, address};
<<"string"/utf8>> ->
{ok, string};
<<"bool"/utf8>> ->
{ok, bool};
<<"boolean"/utf8>> ->
{ok, bool};
<<"bytes32"/utf8>> ->
{ok, {fixed_bytes, 32}};
_ ->
{error,
{parse_error,
<<"Unsupported parameter type: "/utf8, Type_str/binary>>}}
end.
-file("src/gleeth/ethereum/contract.gleam", 119).
-spec parse_uint_value(binary()) -> {ok, gleeth@ethereum@abi@types:abi_value()} |
{error, gleeth@ethereum@abi@types:abi_error()}.
parse_uint_value(Value) ->
case gleam_stdlib:parse_int(Value) of
{ok, N} ->
{ok, {uint_value, N}};
{error, _} ->
case gleeth@utils@hex:to_int(Value) of
{ok, N@1} ->
{ok, {uint_value, N@1}};
{error, _} ->
{error,
{encode_error,
<<"Cannot parse uint value: "/utf8, Value/binary>>}}
end
end.
-file("src/gleeth/ethereum/contract.gleam", 135).
-spec parse_bool_value(binary()) -> {ok, gleeth@ethereum@abi@types:abi_value()} |
{error, gleeth@ethereum@abi@types:abi_error()}.
parse_bool_value(Value) ->
case string:lowercase(Value) of
<<"true"/utf8>> ->
{ok, {bool_value, true}};
<<"1"/utf8>> ->
{ok, {bool_value, true}};
<<"false"/utf8>> ->
{ok, {bool_value, false}};
<<"0"/utf8>> ->
{ok, {bool_value, false}};
_ ->
{error,
{encode_error,
<<"Boolean must be 'true', 'false', '1', or '0'"/utf8>>}}
end.
-file("src/gleeth/ethereum/contract.gleam", 175).
-spec make_zero_bytes_acc(integer(), bitstring()) -> bitstring().
make_zero_bytes_acc(N, Acc) ->
case N =< 0 of
true ->
Acc;
false ->
make_zero_bytes_acc(N - 1, <<Acc/bitstring, 0:8>>)
end.
-file("src/gleeth/ethereum/contract.gleam", 168).
-spec make_zero_bytes(integer()) -> bitstring().
make_zero_bytes(N) ->
case N =< 0 of
true ->
<<>>;
false ->
make_zero_bytes_acc(N, <<>>)
end.
-file("src/gleeth/ethereum/contract.gleam", 148).
-spec parse_bytes32_value(binary()) -> {ok,
gleeth@ethereum@abi@types:abi_value()} |
{error, gleeth@ethereum@abi@types:abi_error()}.
parse_bytes32_value(Value) ->
case gleeth@utils@hex:decode(Value) of
{ok, Bytes} ->
Size = erlang:byte_size(Bytes),
case Size =< 32 of
true ->
Padding = make_zero_bytes(32 - Size),
{ok,
{fixed_bytes_value,
gleam_stdlib:bit_array_concat([Bytes, Padding])}};
false ->
{error, {encode_error, <<"bytes32 value too long"/utf8>>}}
end;
{error, _} ->
{error,
{encode_error,
<<"Invalid hex for bytes32: "/utf8, Value/binary>>}}
end.
-file("src/gleeth/ethereum/contract.gleam", 101).
-spec string_to_abi_value(gleeth@ethereum@abi@types:abi_type(), binary()) -> {ok,
gleeth@ethereum@abi@types:abi_value()} |
{error, gleeth@ethereum@abi@types:abi_error()}.
string_to_abi_value(Abi_type, Value) ->
case Abi_type of
{uint, _} ->
parse_uint_value(Value);
address ->
{ok, {address_value, Value}};
string ->
{ok, {string_value, Value}};
bool ->
parse_bool_value(Value);
{fixed_bytes, _} ->
parse_bytes32_value(Value);
_ ->
{error,
{encode_error,
<<"Unsupported ABI type for CLI parsing: "/utf8,
(gleeth@ethereum@abi@types:to_string(Abi_type))/binary>>}}
end.
-file("src/gleeth/ethereum/contract.gleam", 182).
-spec abi_error_to_gleeth_error(gleeth@ethereum@abi@types:abi_error()) -> gleeth@rpc@types:gleeth_error().
abi_error_to_gleeth_error(Err) ->
{abi_err, Err}.
-file("src/gleeth/ethereum/contract.gleam", 12).
-spec generate_function_selector(
binary(),
list(gleeth@ethereum@abi@types:abi_type())
) -> {ok, binary()} | {error, gleeth@rpc@types:gleeth_error()}.
generate_function_selector(Function_name, Param_types) ->
case gleeth@ethereum@abi@encode:function_selector(
Function_name,
Param_types
) of
{ok, Selector} ->
{ok, gleeth@utils@hex:encode(Selector)};
{error, Err} ->
{error, abi_error_to_gleeth_error(Err)}
end.
-file("src/gleeth/ethereum/contract.gleam", 23).
-spec encode_parameters(
list({gleeth@ethereum@abi@types:abi_type(),
gleeth@ethereum@abi@types:abi_value()})
) -> {ok, binary()} | {error, gleeth@rpc@types:gleeth_error()}.
encode_parameters(Parameters) ->
case Parameters of
[] ->
{ok, <<""/utf8>>};
Params ->
case gleeth@ethereum@abi@encode:encode(Params) of
{ok, Encoded} ->
{ok, string:lowercase(gleam_stdlib:base16_encode(Encoded))};
{error, Err} ->
{error, abi_error_to_gleeth_error(Err)}
end
end.
-file("src/gleeth/ethereum/contract.gleam", 38).
-spec build_call_data(
binary(),
list({gleeth@ethereum@abi@types:abi_type(),
gleeth@ethereum@abi@types:abi_value()})
) -> {ok, binary()} | {error, gleeth@rpc@types:gleeth_error()}.
build_call_data(Function_name, Parameters) ->
Abi_type_list = gleam@list:map(
Parameters,
fun(P) -> erlang:element(1, P) end
),
case gleeth@ethereum@abi@encode:function_selector(
Function_name,
Abi_type_list
) of
{ok, Selector} ->
case Parameters of
[] ->
{ok, gleeth@utils@hex:encode(Selector)};
_ ->
case gleeth@ethereum@abi@encode:encode(Parameters) of
{ok, Encoded} ->
Selector_hex = string:lowercase(
gleam_stdlib:base16_encode(Selector)
),
Params_hex = string:lowercase(
gleam_stdlib:base16_encode(Encoded)
),
{ok,
<<<<"0x"/utf8, Selector_hex/binary>>/binary,
Params_hex/binary>>};
{error, Err} ->
{error, abi_error_to_gleeth_error(Err)}
end
end;
{error, Err@1} ->
{error, abi_error_to_gleeth_error(Err@1)}
end.
-file("src/gleeth/ethereum/contract.gleam", 68).
-spec parse_parameter(binary()) -> {ok,
{gleeth@ethereum@abi@types:abi_type(),
gleeth@ethereum@abi@types:abi_value()}} |
{error, gleeth@rpc@types:gleeth_error()}.
parse_parameter(Param_str) ->
case gleam@string:split(Param_str, <<":"/utf8>>) of
[Type_str, Value] ->
gleam@result:'try'(
parse_abi_type(Type_str),
fun(Abi_type) ->
gleam@result:'try'(
begin
_pipe = string_to_abi_value(Abi_type, Value),
gleam@result:map_error(
_pipe,
fun(E) -> abi_error_to_gleeth_error(E) end
)
end,
fun(Abi_value) -> {ok, {Abi_type, Abi_value}} end
)
end
);
_ ->
{error,
{parse_error,
<<"Parameter must be in format 'type:value'"/utf8>>}}
end.