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

src/gleeth@crypto@transaction.erl

-module(gleeth@crypto@transaction).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/gleeth/crypto/transaction.gleam").
-export([sign_transaction/2, sign_eip1559_transaction/2, create_legacy_transaction/7, create_eth_transfer/6, create_contract_call/6, create_eip1559_transaction/9, signed_transaction_to_string/1, hash_raw_transaction/1, get_transaction_hash/1, get_eip1559_transaction_hash/1, signed_eip1559_transaction_to_string/1, error_to_string/1]).
-export_type([unsigned_transaction/0, signed_transaction/0, eip1559_transaction/0, access_list_entry/0, signed_eip1559_transaction/0, transaction_type/0, transaction_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.
-type unsigned_transaction() :: {unsigned_transaction,
binary(),
binary(),
binary(),
binary(),
binary(),
binary(),
integer()}.
-type signed_transaction() :: {signed_transaction,
binary(),
binary(),
binary(),
binary(),
binary(),
binary(),
integer(),
binary(),
binary(),
binary(),
binary()}.
-type eip1559_transaction() :: {eip1559_transaction,
binary(),
binary(),
binary(),
binary(),
binary(),
binary(),
binary(),
integer(),
list(access_list_entry())}.
-type access_list_entry() :: {access_list_entry, binary(), list(binary())}.
-type signed_eip1559_transaction() :: {signed_eip1559_transaction,
binary(),
binary(),
binary(),
binary(),
binary(),
binary(),
binary(),
integer(),
list(access_list_entry()),
binary(),
binary(),
binary(),
binary()}.
-type transaction_type() :: legacy | access_list | eip1559.
-type transaction_error() :: {invalid_address, binary()} |
{invalid_amount, binary()} |
{invalid_gas, binary()} |
{invalid_nonce, binary()} |
{invalid_chain_id, binary()} |
{invalid_data, binary()} |
{signing_failed, binary()} |
{encoding_failed, binary()}.
-file("src/gleeth/crypto/transaction.gleam", 458).
?DOC(
" Encode a hex string as raw bytes without stripping leading zeros.\n"
" Used for address and data fields which are byte strings, not integers.\n"
).
-spec encode_raw_hex(binary()) -> gleeth@encoding@rlp:rlp_item().
encode_raw_hex(Hex_string) ->
case gleeth@utils@hex:decode(Hex_string) of
{ok, Bytes} ->
{rlp_bytes, Bytes};
{error, _} ->
{rlp_bytes, <<>>}
end.
-file("src/gleeth/crypto/transaction.gleam", 364).
?DOC(" EIP-155 signing hash: keccak256(RLP([nonce, gasPrice, gasLimit, to, value, data, chainId, 0, 0]))\n").
-spec create_signing_hash(unsigned_transaction()) -> bitstring().
create_signing_hash(Transaction) ->
Items = {rlp_list,
[gleeth@encoding@rlp:encode_hex_field(erlang:element(6, Transaction)),
gleeth@encoding@rlp:encode_hex_field(erlang:element(5, Transaction)),
gleeth@encoding@rlp:encode_hex_field(erlang:element(4, Transaction)),
encode_raw_hex(erlang:element(2, Transaction)),
gleeth@encoding@rlp:encode_hex_field(erlang:element(3, Transaction)),
encode_raw_hex(erlang:element(7, Transaction)),
gleeth@encoding@rlp:encode_int(erlang:element(8, Transaction)),
gleeth@encoding@rlp:encode_int(0),
gleeth@encoding@rlp:encode_int(0)]},
gleeth@crypto@keccak:keccak256_binary(gleeth@encoding@rlp:encode(Items)).
-file("src/gleeth/crypto/transaction.gleam", 451).
-spec encode_access_list_entry(access_list_entry()) -> gleeth@encoding@rlp:rlp_item().
encode_access_list_entry(Entry) ->
Storage_keys = gleam@list:map(
erlang:element(3, Entry),
fun encode_raw_hex/1
),
{rlp_list,
[encode_raw_hex(erlang:element(2, Entry)), {rlp_list, Storage_keys}]}.
-file("src/gleeth/crypto/transaction.gleam", 447).
?DOC(" Encode an access list as an RLP list of [address, [storageKeys]] entries\n").
-spec encode_access_list(list(access_list_entry())) -> gleeth@encoding@rlp:rlp_item().
encode_access_list(Entries) ->
{rlp_list, gleam@list:map(Entries, fun encode_access_list_entry/1)}.
-file("src/gleeth/crypto/transaction.gleam", 403).
?DOC(" EIP-1559 signing hash: keccak256(0x02 || RLP([chainId, nonce, maxPriorityFeePerGas, maxFeePerGas, gasLimit, to, value, data, accessList]))\n").
-spec create_eip1559_signing_hash(eip1559_transaction()) -> bitstring().
create_eip1559_signing_hash(Transaction) ->
Items = {rlp_list,
[gleeth@encoding@rlp:encode_int(erlang:element(9, Transaction)),
gleeth@encoding@rlp:encode_hex_field(erlang:element(7, Transaction)),
gleeth@encoding@rlp:encode_hex_field(erlang:element(6, Transaction)),
gleeth@encoding@rlp:encode_hex_field(erlang:element(5, Transaction)),
gleeth@encoding@rlp:encode_hex_field(erlang:element(4, Transaction)),
encode_raw_hex(erlang:element(2, Transaction)),
gleeth@encoding@rlp:encode_hex_field(erlang:element(3, Transaction)),
encode_raw_hex(erlang:element(8, Transaction)),
encode_access_list(erlang:element(10, Transaction))]},
Payload = gleeth@encoding@rlp:encode(Items),
gleeth@crypto@keccak:keccak256_binary(<<16#02, Payload/bitstring>>).
-file("src/gleeth/crypto/transaction.gleam", 466).
?DOC(" Strip leading zero bytes for minimal big-endian integer encoding\n").
-spec strip_leading_zeros(bitstring()) -> bitstring().
strip_leading_zeros(Data) ->
case Data of
<<0:8, Rest/bitstring>> ->
strip_leading_zeros(Rest);
_ ->
Data
end.
-file("src/gleeth/crypto/transaction.gleam", 381).
?DOC(" RLP-encode the signed transaction: [nonce, gasPrice, gasLimit, to, value, data, v, r, s]\n").
-spec create_raw_transaction(
unsigned_transaction(),
integer(),
bitstring(),
bitstring()
) -> binary().
create_raw_transaction(Transaction, V, R, S) ->
Items = {rlp_list,
[gleeth@encoding@rlp:encode_hex_field(erlang:element(6, Transaction)),
gleeth@encoding@rlp:encode_hex_field(erlang:element(5, Transaction)),
gleeth@encoding@rlp:encode_hex_field(erlang:element(4, Transaction)),
encode_raw_hex(erlang:element(2, Transaction)),
gleeth@encoding@rlp:encode_hex_field(erlang:element(3, Transaction)),
encode_raw_hex(erlang:element(7, Transaction)),
gleeth@encoding@rlp:encode_int(V),
{rlp_bytes, strip_leading_zeros(R)},
{rlp_bytes, strip_leading_zeros(S)}]},
gleeth@utils@hex:encode(gleeth@encoding@rlp:encode(Items)).
-file("src/gleeth/crypto/transaction.gleam", 277).
?DOC(
" Sign a legacy (EIP-155) transaction with a wallet.\n"
" Produces an RLP-encoded raw transaction suitable for eth_sendRawTransaction.\n"
).
-spec sign_transaction(unsigned_transaction(), gleeth@crypto@wallet:wallet()) -> {ok,
signed_transaction()} |
{error, transaction_error()}.
sign_transaction(Transaction, Wallet) ->
Signing_hash = create_signing_hash(Transaction),
gleam@result:'try'(
begin
_pipe = gleeth@crypto@wallet:sign_hash(Wallet, Signing_hash),
gleam@result:map_error(
_pipe,
fun(Err) ->
{signing_failed,
<<"Failed to sign transaction: "/utf8,
(gleeth@crypto@wallet:error_to_string(Err))/binary>>}
end
)
end,
fun(Signature) ->
Eip155_v = (erlang:element(4, Signature) + (2 * erlang:element(
8,
Transaction
)))
+ 35,
V_hex = <<"0x"/utf8,
(string:lowercase(gleam@int:to_base16(Eip155_v)))/binary>>,
R_hex = gleeth@utils@hex:encode(erlang:element(2, Signature)),
S_hex = gleeth@utils@hex:encode(erlang:element(3, Signature)),
Raw_tx = create_raw_transaction(
Transaction,
Eip155_v,
erlang:element(2, Signature),
erlang:element(3, Signature)
),
{ok,
{signed_transaction,
erlang:element(2, Transaction),
erlang:element(3, Transaction),
erlang:element(4, Transaction),
erlang:element(5, Transaction),
erlang:element(6, Transaction),
erlang:element(7, Transaction),
erlang:element(8, Transaction),
V_hex,
R_hex,
S_hex,
Raw_tx}}
end
).
-file("src/gleeth/crypto/transaction.gleam", 421).
?DOC(" RLP-encode the signed EIP-1559 transaction: 0x02 || RLP([chainId, nonce, maxPriorityFeePerGas, maxFeePerGas, gasLimit, to, value, data, accessList, v, r, s])\n").
-spec create_eip1559_raw_transaction(
eip1559_transaction(),
integer(),
bitstring(),
bitstring()
) -> binary().
create_eip1559_raw_transaction(Transaction, V, R, S) ->
Items = {rlp_list,
[gleeth@encoding@rlp:encode_int(erlang:element(9, Transaction)),
gleeth@encoding@rlp:encode_hex_field(erlang:element(7, Transaction)),
gleeth@encoding@rlp:encode_hex_field(erlang:element(6, Transaction)),
gleeth@encoding@rlp:encode_hex_field(erlang:element(5, Transaction)),
gleeth@encoding@rlp:encode_hex_field(erlang:element(4, Transaction)),
encode_raw_hex(erlang:element(2, Transaction)),
gleeth@encoding@rlp:encode_hex_field(erlang:element(3, Transaction)),
encode_raw_hex(erlang:element(8, Transaction)),
encode_access_list(erlang:element(10, Transaction)),
gleeth@encoding@rlp:encode_int(V),
{rlp_bytes, strip_leading_zeros(R)},
{rlp_bytes, strip_leading_zeros(S)}]},
Payload = gleeth@encoding@rlp:encode(Items),
gleeth@utils@hex:encode(<<16#02, Payload/bitstring>>).
-file("src/gleeth/crypto/transaction.gleam", 318).
?DOC(
" Sign an EIP-1559 (Type 2) transaction with a wallet.\n"
" Produces a type-prefixed RLP-encoded raw transaction: 0x02 || RLP([...]).\n"
).
-spec sign_eip1559_transaction(
eip1559_transaction(),
gleeth@crypto@wallet:wallet()
) -> {ok, signed_eip1559_transaction()} | {error, transaction_error()}.
sign_eip1559_transaction(Transaction, Wallet) ->
Signing_hash = create_eip1559_signing_hash(Transaction),
gleam@result:'try'(
begin
_pipe = gleeth@crypto@wallet:sign_hash(Wallet, Signing_hash),
gleam@result:map_error(
_pipe,
fun(Err) ->
{signing_failed,
<<"Failed to sign transaction: "/utf8,
(gleeth@crypto@wallet:error_to_string(Err))/binary>>}
end
)
end,
fun(Signature) ->
V = erlang:element(4, Signature),
V_hex = <<"0x"/utf8,
(string:lowercase(gleam@int:to_base16(V)))/binary>>,
R_hex = gleeth@utils@hex:encode(erlang:element(2, Signature)),
S_hex = gleeth@utils@hex:encode(erlang:element(3, Signature)),
Raw_tx = create_eip1559_raw_transaction(
Transaction,
V,
erlang:element(2, Signature),
erlang:element(3, Signature)
),
{ok,
{signed_eip1559_transaction,
erlang:element(2, Transaction),
erlang:element(3, Transaction),
erlang:element(4, Transaction),
erlang:element(5, Transaction),
erlang:element(6, Transaction),
erlang:element(7, Transaction),
erlang:element(8, Transaction),
erlang:element(9, Transaction),
erlang:element(10, Transaction),
V_hex,
R_hex,
S_hex,
Raw_tx}}
end
).
-file("src/gleeth/crypto/transaction.gleam", 530).
?DOC(" Validate chain ID\n").
-spec validate_chain_id(integer()) -> {ok, nil} | {error, transaction_error()}.
validate_chain_id(Chain_id) ->
case Chain_id > 0 of
true ->
{ok, nil};
false ->
{error, {invalid_chain_id, <<"Chain ID must be positive"/utf8>>}}
end.
-file("src/gleeth/crypto/transaction.gleam", 538).
?DOC(" Check if character is valid hex\n").
-spec is_hex_char(binary()) -> boolean().
is_hex_char(Char) ->
case Char of
<<"0"/utf8>> ->
true;
<<"1"/utf8>> ->
true;
<<"2"/utf8>> ->
true;
<<"3"/utf8>> ->
true;
<<"4"/utf8>> ->
true;
<<"5"/utf8>> ->
true;
<<"6"/utf8>> ->
true;
<<"7"/utf8>> ->
true;
<<"8"/utf8>> ->
true;
<<"9"/utf8>> ->
true;
<<"a"/utf8>> ->
true;
<<"b"/utf8>> ->
true;
<<"c"/utf8>> ->
true;
<<"d"/utf8>> ->
true;
<<"e"/utf8>> ->
true;
<<"f"/utf8>> ->
true;
<<"A"/utf8>> ->
true;
<<"B"/utf8>> ->
true;
<<"C"/utf8>> ->
true;
<<"D"/utf8>> ->
true;
<<"E"/utf8>> ->
true;
<<"F"/utf8>> ->
true;
_ ->
false
end.
-file("src/gleeth/crypto/transaction.gleam", 478).
?DOC(" Validate Ethereum address format\n").
-spec validate_address(binary()) -> {ok, nil} | {error, transaction_error()}.
validate_address(Address) ->
Cleaned = case gleam_stdlib:string_starts_with(Address, <<"0x"/utf8>>) of
true ->
gleam@string:drop_start(Address, 2);
false ->
Address
end,
case string:length(Cleaned) of
40 ->
case begin
_pipe = gleam@string:to_graphemes(Cleaned),
gleam@list:all(_pipe, fun is_hex_char/1)
end of
true ->
{ok, nil};
false ->
{error,
{invalid_address,
<<"Address contains non-hex characters"/utf8>>}}
end;
0 ->
{ok, nil};
_ ->
{error,
{invalid_address, <<"Address must be 40 hex characters"/utf8>>}}
end.
-file("src/gleeth/crypto/transaction.gleam", 498).
?DOC(" Validate hex amount (like value, gas, nonce)\n").
-spec validate_hex_amount(binary()) -> {ok, nil} | {error, transaction_error()}.
validate_hex_amount(Amount) ->
Cleaned = case gleam_stdlib:string_starts_with(Amount, <<"0x"/utf8>>) of
true ->
gleam@string:drop_start(Amount, 2);
false ->
Amount
end,
case begin
_pipe = gleam@string:to_graphemes(Cleaned),
gleam@list:all(_pipe, fun is_hex_char/1)
end of
true ->
{ok, nil};
false ->
{error,
{invalid_amount, <<"Amount contains non-hex characters"/utf8>>}}
end.
-file("src/gleeth/crypto/transaction.gleam", 511).
?DOC(" Validate hex data\n").
-spec validate_hex_data(binary()) -> {ok, nil} | {error, transaction_error()}.
validate_hex_data(Data) ->
case Data of
<<"0x"/utf8>> ->
{ok, nil};
_ ->
Cleaned = case gleam_stdlib:string_starts_with(Data, <<"0x"/utf8>>) of
true ->
gleam@string:drop_start(Data, 2);
false ->
Data
end,
case begin
_pipe = gleam@string:to_graphemes(Cleaned),
gleam@list:all(_pipe, fun is_hex_char/1)
end of
true ->
{ok, nil};
false ->
{error,
{invalid_data,
<<"Data contains non-hex characters"/utf8>>}}
end
end.
-file("src/gleeth/crypto/transaction.gleam", 552).
?DOC(" Normalize address to lowercase with 0x prefix\n").
-spec normalize_address(binary()) -> binary().
normalize_address(Address) ->
case Address of
<<""/utf8>> ->
<<""/utf8>>;
_ ->
Cleaned = case gleam_stdlib:string_starts_with(
Address,
<<"0x"/utf8>>
) of
true ->
gleam@string:drop_start(Address, 2);
false ->
Address
end,
<<"0x"/utf8, (string:lowercase(Cleaned))/binary>>
end.
-file("src/gleeth/crypto/transaction.gleam", 566).
?DOC(" Normalize hex string to lowercase with 0x prefix\n").
-spec normalize_hex(binary()) -> binary().
normalize_hex(Hex) ->
Cleaned = case gleam_stdlib:string_starts_with(Hex, <<"0x"/utf8>>) of
true ->
gleam@string:drop_start(Hex, 2);
false ->
Hex
end,
<<"0x"/utf8, (string:lowercase(Cleaned))/binary>>.
-file("src/gleeth/crypto/transaction.gleam", 575).
?DOC(" Normalize hex data (keep \"0x\" for empty data)\n").
-spec normalize_hex_data(binary()) -> binary().
normalize_hex_data(Data) ->
case Data of
<<""/utf8>> ->
<<"0x"/utf8>>;
<<"0x"/utf8>> ->
<<"0x"/utf8>>;
_ ->
normalize_hex(Data)
end.
-file("src/gleeth/crypto/transaction.gleam", 147).
?DOC(
" Create a new unsigned legacy (Type 0) transaction.\n"
"\n"
" All numeric parameters must be `0x`-prefixed hex strings. The Ethereum\n"
" JSON-RPC API returns values in this format, so results from\n"
" `methods.get_gas_price`, `methods.get_transaction_count`, etc. can be\n"
" passed directly.\n"
"\n"
" - `to` - recipient address (`\"0x...\"`, 40 hex chars after prefix)\n"
" - `value` - amount in wei as hex (e.g. `\"0xde0b6b3a7640000\"` for 1 ETH)\n"
" - `gas_limit` - gas limit as hex (e.g. `\"0x5208\"` for 21000)\n"
" - `gas_price` - gas price in wei as hex\n"
" - `nonce` - sender's transaction count as hex\n"
" - `data` - calldata as hex (`\"0x\"` for simple transfers)\n"
" - `chain_id` - network chain ID as integer (1 for mainnet, 11155111 for Sepolia)\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" let assert Ok(tx) = transaction.create_legacy_transaction(\n"
" \"0x70997970C51812dc3A010C7d01b50e0d17dc79C8\",\n"
" \"0xde0b6b3a7640000\", // 1 ETH in wei\n"
" \"0x5208\", // 21000 gas\n"
" \"0x3b9aca00\", // 1 gwei gas price\n"
" \"0x0\", // nonce 0\n"
" \"0x\", // no calldata\n"
" 1, // mainnet\n"
" )\n"
" ```\n"
).
-spec create_legacy_transaction(
binary(),
binary(),
binary(),
binary(),
binary(),
binary(),
integer()
) -> {ok, unsigned_transaction()} | {error, transaction_error()}.
create_legacy_transaction(
To,
Value,
Gas_limit,
Gas_price,
Nonce,
Data,
Chain_id
) ->
gleam@result:'try'(
validate_address(To),
fun(_) ->
gleam@result:'try'(
validate_hex_amount(Value),
fun(_) ->
gleam@result:'try'(
validate_hex_amount(Gas_limit),
fun(_) ->
gleam@result:'try'(
validate_hex_amount(Gas_price),
fun(_) ->
gleam@result:'try'(
validate_hex_amount(Nonce),
fun(_) ->
gleam@result:'try'(
validate_hex_data(Data),
fun(_) ->
gleam@result:'try'(
validate_chain_id(
Chain_id
),
fun(_) ->
{ok,
{unsigned_transaction,
normalize_address(
To
),
normalize_hex(
Value
),
normalize_hex(
Gas_limit
),
normalize_hex(
Gas_price
),
normalize_hex(
Nonce
),
normalize_hex_data(
Data
),
Chain_id}}
end
)
end
)
end
)
end
)
end
)
end
)
end
).
-file("src/gleeth/crypto/transaction.gleam", 180).
?DOC(
" Create a simple ETH transfer transaction (no calldata).\n"
"\n"
" Convenience wrapper around `create_legacy_transaction` with `data` set to\n"
" `\"0x\"`. All numeric parameters are `0x`-prefixed hex strings.\n"
).
-spec create_eth_transfer(
binary(),
binary(),
binary(),
binary(),
binary(),
integer()
) -> {ok, unsigned_transaction()} | {error, transaction_error()}.
create_eth_transfer(To, Value_wei, Gas_limit, Gas_price, Nonce, Chain_id) ->
create_legacy_transaction(
To,
Value_wei,
Gas_limit,
Gas_price,
Nonce,
<<"0x"/utf8>>,
Chain_id
).
-file("src/gleeth/crypto/transaction.gleam", 203).
?DOC(
" Create a contract interaction transaction (zero value).\n"
"\n"
" Convenience wrapper around `create_legacy_transaction` with `value` set to\n"
" `\"0x0\"`. All numeric parameters are `0x`-prefixed hex strings.\n"
).
-spec create_contract_call(
binary(),
binary(),
binary(),
binary(),
binary(),
integer()
) -> {ok, unsigned_transaction()} | {error, transaction_error()}.
create_contract_call(
Contract_address,
Call_data,
Gas_limit,
Gas_price,
Nonce,
Chain_id
) ->
create_legacy_transaction(
Contract_address,
<<"0x0"/utf8>>,
Gas_limit,
Gas_price,
Nonce,
Call_data,
Chain_id
).
-file("src/gleeth/crypto/transaction.gleam", 238).
?DOC(
" Create and validate an EIP-1559 (Type 2) transaction.\n"
"\n"
" All numeric parameters must be `0x`-prefixed hex strings. Fee parameters\n"
" from `methods.get_gas_price` and `methods.get_max_priority_fee` can be\n"
" passed directly.\n"
"\n"
" - `to` - recipient address\n"
" - `value` - amount in wei as hex\n"
" - `gas_limit` - gas limit as hex\n"
" - `max_fee_per_gas` - maximum total fee per gas in wei as hex\n"
" - `max_priority_fee_per_gas` - tip per gas in wei as hex\n"
" - `nonce` - sender's transaction count as hex\n"
" - `data` - calldata as hex (`\"0x\"` for simple transfers)\n"
" - `chain_id` - network chain ID as integer\n"
" - `access_list` - EIP-2930 access list (pass `[]` if not needed)\n"
).
-spec create_eip1559_transaction(
binary(),
binary(),
binary(),
binary(),
binary(),
binary(),
binary(),
integer(),
list(access_list_entry())
) -> {ok, eip1559_transaction()} | {error, transaction_error()}.
create_eip1559_transaction(
To,
Value,
Gas_limit,
Max_fee_per_gas,
Max_priority_fee_per_gas,
Nonce,
Data,
Chain_id,
Access_list
) ->
gleam@result:'try'(
validate_address(To),
fun(_) ->
gleam@result:'try'(
validate_hex_amount(Value),
fun(_) ->
gleam@result:'try'(
validate_hex_amount(Gas_limit),
fun(_) ->
gleam@result:'try'(
validate_hex_amount(Max_fee_per_gas),
fun(_) ->
gleam@result:'try'(
validate_hex_amount(
Max_priority_fee_per_gas
),
fun(_) ->
gleam@result:'try'(
validate_hex_amount(Nonce),
fun(_) ->
gleam@result:'try'(
validate_hex_data(Data),
fun(_) ->
gleam@result:'try'(
validate_chain_id(
Chain_id
),
fun(_) ->
{ok,
{eip1559_transaction,
normalize_address(
To
),
normalize_hex(
Value
),
normalize_hex(
Gas_limit
),
normalize_hex(
Max_fee_per_gas
),
normalize_hex(
Max_priority_fee_per_gas
),
normalize_hex(
Nonce
),
normalize_hex_data(
Data
),
Chain_id,
Access_list}}
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
).
-file("src/gleeth/crypto/transaction.gleam", 588).
?DOC(" Convert signed transaction to string for display\n").
-spec signed_transaction_to_string(signed_transaction()) -> binary().
signed_transaction_to_string(Tx) ->
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"SignedTransaction {\n"/utf8,
" to: "/utf8>>/binary,
(erlang:element(
2,
Tx
))/binary>>/binary,
"\n"/utf8>>/binary,
" value: "/utf8>>/binary,
(erlang:element(
3,
Tx
))/binary>>/binary,
"\n"/utf8>>/binary,
" gas_limit: "/utf8>>/binary,
(erlang:element(
4,
Tx
))/binary>>/binary,
"\n"/utf8>>/binary,
" gas_price: "/utf8>>/binary,
(erlang:element(
5,
Tx
))/binary>>/binary,
"\n"/utf8>>/binary,
" nonce: "/utf8>>/binary,
(erlang:element(
6,
Tx
))/binary>>/binary,
"\n"/utf8>>/binary,
" data: "/utf8>>/binary,
(erlang:element(
7,
Tx
))/binary>>/binary,
"\n"/utf8>>/binary,
" chain_id: "/utf8>>/binary,
(erlang:integer_to_binary(
erlang:element(
8,
Tx
)
))/binary>>/binary,
"\n"/utf8>>/binary,
" v: "/utf8>>/binary,
(erlang:element(9, Tx))/binary>>/binary,
"\n"/utf8>>/binary,
" r: "/utf8>>/binary,
(erlang:element(10, Tx))/binary>>/binary,
"\n"/utf8>>/binary,
" s: "/utf8>>/binary,
(erlang:element(11, Tx))/binary>>/binary,
"\n"/utf8>>/binary,
" raw: "/utf8>>/binary,
(erlang:element(12, Tx))/binary>>/binary,
"\n"/utf8>>/binary,
"}"/utf8>>.
-file("src/gleeth/crypto/transaction.gleam", 637).
?DOC(" Hash a raw transaction hex string to get its transaction hash\n").
-spec hash_raw_transaction(binary()) -> binary().
hash_raw_transaction(Raw_transaction) ->
case gleeth@utils@hex:decode(Raw_transaction) of
{ok, Raw_bytes} ->
gleeth@utils@hex:encode(
gleeth@crypto@keccak:keccak256_binary(Raw_bytes)
);
{error, _} ->
<<""/utf8>>
end.
-file("src/gleeth/crypto/transaction.gleam", 627).
?DOC(" Get transaction hash from a signed legacy transaction\n").
-spec get_transaction_hash(signed_transaction()) -> binary().
get_transaction_hash(Tx) ->
hash_raw_transaction(erlang:element(12, Tx)).
-file("src/gleeth/crypto/transaction.gleam", 632).
?DOC(" Get transaction hash from a signed EIP-1559 transaction\n").
-spec get_eip1559_transaction_hash(signed_eip1559_transaction()) -> binary().
get_eip1559_transaction_hash(Tx) ->
hash_raw_transaction(erlang:element(14, Tx)).
-file("src/gleeth/crypto/transaction.gleam", 645).
?DOC(" Convert signed EIP-1559 transaction to string for display\n").
-spec signed_eip1559_transaction_to_string(signed_eip1559_transaction()) -> binary().
signed_eip1559_transaction_to_string(Tx) ->
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"SignedEip1559Transaction {\n"/utf8,
" to: "/utf8>>/binary,
(erlang:element(
2,
Tx
))/binary>>/binary,
"\n"/utf8>>/binary,
" value: "/utf8>>/binary,
(erlang:element(
3,
Tx
))/binary>>/binary,
"\n"/utf8>>/binary,
" gas_limit: "/utf8>>/binary,
(erlang:element(
4,
Tx
))/binary>>/binary,
"\n"/utf8>>/binary,
" max_fee_per_gas: "/utf8>>/binary,
(erlang:element(
5,
Tx
))/binary>>/binary,
"\n"/utf8>>/binary,
" max_priority_fee_per_gas: "/utf8>>/binary,
(erlang:element(
6,
Tx
))/binary>>/binary,
"\n"/utf8>>/binary,
" nonce: "/utf8>>/binary,
(erlang:element(
7,
Tx
))/binary>>/binary,
"\n"/utf8>>/binary,
" data: "/utf8>>/binary,
(erlang:element(
8,
Tx
))/binary>>/binary,
"\n"/utf8>>/binary,
" chain_id: "/utf8>>/binary,
(erlang:integer_to_binary(
erlang:element(
9,
Tx
)
))/binary>>/binary,
"\n"/utf8>>/binary,
" v: "/utf8>>/binary,
(erlang:element(11, Tx))/binary>>/binary,
"\n"/utf8>>/binary,
" r: "/utf8>>/binary,
(erlang:element(12, Tx))/binary>>/binary,
"\n"/utf8>>/binary,
" s: "/utf8>>/binary,
(erlang:element(13, Tx))/binary>>/binary,
"\n"/utf8>>/binary,
" raw: "/utf8>>/binary,
(erlang:element(14, Tx))/binary>>/binary,
"\n"/utf8>>/binary,
"}"/utf8>>.
-file("src/gleeth/crypto/transaction.gleam", 689).
?DOC(" Convert TransactionError to string\n").
-spec error_to_string(transaction_error()) -> binary().
error_to_string(Error) ->
case Error of
{invalid_address, Msg} ->
<<"Invalid address: "/utf8, Msg/binary>>;
{invalid_amount, Msg@1} ->
<<"Invalid amount: "/utf8, Msg@1/binary>>;
{invalid_gas, Msg@2} ->
<<"Invalid gas: "/utf8, Msg@2/binary>>;
{invalid_nonce, Msg@3} ->
<<"Invalid nonce: "/utf8, Msg@3/binary>>;
{invalid_chain_id, Msg@4} ->
<<"Invalid chain ID: "/utf8, Msg@4/binary>>;
{invalid_data, Msg@5} ->
<<"Invalid data: "/utf8, Msg@5/binary>>;
{signing_failed, Msg@6} ->
<<"Signing failed: "/utf8, Msg@6/binary>>;
{encoding_failed, Msg@7} ->
<<"Encoding failed: "/utf8, Msg@7/binary>>
end.