Skip to content

Commit 7a2cddb

Browse files
authored
Add Ethers.blob_base_fee/1 and fix minor encoding bugs (#180)
* Add `Ethres.blob_fee_per_gas/1` * Fix transaction encoding * Update ethereumex version requirement * Add margin to max_fee_per_blob_gas * Enhance fee margin configuration and docs * Fix CHANGELOG * Fix credo warnings
1 parent 314e911 commit 7a2cddb

File tree

9 files changed

+206
-16
lines changed

9 files changed

+206
-16
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,13 @@
77
- Support [EIP-1191](https://eips.ethereum.org/EIPS/eip-1191): Add chain id to mixed-case checksum address encoding
88
- Add [EIP-4844](https://eips.ethereum.org/EIPS/eip-4844) transaction support
99
- Add [EIP-2930](https://eips.ethereum.org/EIPS/eip-2930) transaction support
10+
- Add `Ethers.blob_base_fee/1` to calculate blob fee per gas
11+
- Make default gas and fee margin configurable
12+
13+
### Bug Fixes
14+
15+
- Fix encoding of transactions without any input data
16+
- Encode `access_list` and `blob_versioned_hashed` correctly in RPC transaction requests
1017

1118
## v0.6.1 (2025-01-02)
1219

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,9 @@ config :ethers,
7575
json_module: Jason, # Defaults to: Jason
7676
secp256k1_module: ExSecp256k1, # Defaults to: ExSecp256k1
7777
default_signer: nil, # Defaults to: nil, see Ethers.Signer for more info
78-
default_signer_opts: [] # Defaults to: []
78+
default_signer_opts: [], # Defaults to: []
79+
default_gas_margin: 11000, # Precision is 0.01% (11000 = 110%)
80+
default_mdefault_max_fee_per_gas_margin: 12000 #Precision is 0.01% (12000 = 120%)
7981

8082
# If using Ethereumex, you can specify a default JSON-RPC server url here for all requests.
8183
config :ethereumex, url: "[URL_HERE]"

lib/ethers.ex

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ defmodule Ethers do
7777
:get_balance,
7878
:get_transaction_count,
7979
:max_priority_fee_per_gas,
80+
:blob_base_fee,
8081
:gas_price
8182
]
8283
@rpc_actions_map %{
@@ -91,6 +92,7 @@ defmodule Ethers do
9192
get_transaction: :eth_get_transaction_by_hash,
9293
max_priority_fee_per_gas: :eth_max_priority_fee_per_gas,
9394
send_transaction: :eth_send_transaction,
95+
blob_base_fee: :eth_blob_base_fee,
9496
# Deprecated, kept for backward compatibility
9597
send: :eth_send_transaction
9698
}
@@ -525,6 +527,29 @@ defmodule Ethers do
525527
end
526528
end
527529

530+
@doc """
531+
Returns the current blob base fee from the RPC API
532+
"""
533+
@spec blob_base_fee(Keyword.t()) ::
534+
{:ok, non_neg_integer()} | {:error, reason :: term()}
535+
def blob_base_fee(opts \\ []) do
536+
{rpc_client, rpc_opts} = get_rpc_client(opts)
537+
538+
rpc_client.eth_blob_base_fee(rpc_opts)
539+
|> post_process(nil, :blob_base_fee)
540+
end
541+
542+
@doc """
543+
Same as `Ethers.blob_base_fee/1` but raises on error.
544+
"""
545+
@spec blob_base_fee!(Keyword.t()) :: non_neg_integer() | no_return()
546+
def blob_base_fee!(opts \\ []) do
547+
case blob_base_fee(opts) do
548+
{:ok, fee} -> fee
549+
{:error, reason} -> raise ExecutionError, reason
550+
end
551+
end
552+
528553
@doc """
529554
Fetches the event logs with the given filter.
530555

lib/ethers/rpc_client/adapter.ex

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ defmodule Ethers.RpcClient.Adapter do
2929

3030
@callback eth_max_priority_fee_per_gas(keyword()) :: {:ok, binary()} | error()
3131

32+
@callback eth_blob_base_fee(keyword()) :: {:ok, binary()} | error()
33+
3234
@callback eth_get_logs(map(), keyword()) :: {:ok, [binary()] | [map()]} | error()
3335

3436
@callback eth_send_transaction(map(), keyword()) :: {:ok, binary()} | error()

lib/ethers/transaction.ex

Lines changed: 41 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ defmodule Ethers.Transaction do
3636
max_priority_fee_per_gas: :maxPriorityFeePerGas
3737
}
3838

39+
# Margin precision is 0.01% (12345 = 123.45%)
40+
@margin_precision 10_000
41+
3942
@typedoc """
4043
EVM Transaction type
4144
"""
@@ -82,9 +85,9 @@ defmodule Ethers.Transaction do
8285
case Map.fetch(params, :type) do
8386
{:ok, type} when type in @transaction_types ->
8487
input =
85-
params
86-
|> Map.get(:input, Map.get(params, :data))
87-
|> Utils.hex_decode!()
88+
if input_hex = Map.get(params, :input, Map.get(params, :data)) do
89+
Utils.hex_decode!(input_hex)
90+
end
8891

8992
params
9093
|> Map.put(:input, input)
@@ -318,7 +321,10 @@ defmodule Ethers.Transaction do
318321
{field, Utils.integer_to_hex(value)}
319322

320323
{:access_list, al} when is_list(al) ->
321-
{:access_list, al}
324+
{:access_list, encode_access_list(al)}
325+
326+
{:blob_versioned_hashes, hashes} when is_list(hashes) ->
327+
{:blob_versioned_hashes, Enum.map(hashes, &Utils.hex_encode/1)}
322328

323329
{:type, type} when is_atom(type) ->
324330
# Type will get replaced with hex value
@@ -339,6 +345,15 @@ defmodule Ethers.Transaction do
339345
)
340346
end
341347

348+
defp encode_access_list(access_list) do
349+
Enum.map(access_list, fn [address, storage_keys] ->
350+
[
351+
Utils.encode_address!(address),
352+
Enum.map(storage_keys, &Utils.hex_encode/1)
353+
]
354+
end)
355+
end
356+
342357
@doc false
343358
@deprecated "Use Transaction.Signed.calculate_y_parity_or_v/2 instead"
344359
defdelegate calculate_y_parity_or_v(tx, recovery_id), to: Signed
@@ -351,6 +366,7 @@ defmodule Ethers.Transaction do
351366
defp fill_action(:nonce, tx), do: {:get_transaction_count, tx.from, block: "latest"}
352367
defp fill_action(:max_fee_per_gas, _tx), do: :gas_price
353368
defp fill_action(:max_priority_fee_per_gas, _tx), do: :max_priority_fee_per_gas
369+
defp fill_action(:max_fee_per_blob_gas, _tx), do: :blob_base_fee
354370
defp fill_action(:gas_price, _tx), do: :gas_price
355371
defp fill_action(:gas, tx), do: {:estimate_gas, tx}
356372

@@ -362,17 +378,16 @@ defmodule Ethers.Transaction do
362378
end
363379
end
364380

365-
defp do_post_process(:max_fee_per_gas, {:ok, max_fee_per_gas}) do
366-
# Setting a higher value for max_fee_per gas since the actual base fee is
367-
# determined by the last block. This way we minimize the chance to get stuck in
368-
# queue when base fee increases
369-
mex_fee_per_gas = div(max_fee_per_gas * 120, 100)
370-
{:ok, {:max_fee_per_gas, mex_fee_per_gas}}
381+
defp do_post_process(field, {:ok, value})
382+
when field in [:max_fee_per_gas, :max_fee_per_blob_gas] do
383+
# Setting a higher value for max_fee_per and max_fee_per_blob_gas gas since the actual base
384+
# fee is determined by the last block. This way we minimize the chance to get stuck in
385+
# queue when base fee increases.
386+
{:ok, {field, max_fee_per_gas_with_margin(value)}}
371387
end
372388

373389
defp do_post_process(:gas, {:ok, gas}) do
374-
gas = div(gas * 110, 100)
375-
{:ok, {:gas, gas}}
390+
{:ok, {:gas, gas_with_margin(gas)}}
376391
end
377392

378393
defp do_post_process(key, {:ok, v_int}) when is_integer(v_int) do
@@ -412,4 +427,18 @@ defmodule Ethers.Transaction do
412427

413428
@doc false
414429
def default_transaction_type, do: @default_transaction_type
430+
431+
defp gas_with_margin(value) do
432+
margin = Application.get_env(:ethers, :default_gas_margin, 11_000)
433+
with_margin(value, margin)
434+
end
435+
436+
defp max_fee_per_gas_with_margin(value) do
437+
margin = Application.get_env(:ethers, :default_max_fee_per_gas_margin, 12_000)
438+
with_margin(value, margin)
439+
end
440+
441+
defp with_margin(value, margin) do
442+
div(value * margin, @margin_precision)
443+
end
415444
end

mix.exs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ defmodule Ethers.MixProject do
104104
[
105105
{:credo, "~> 1.7", only: [:dev, :test], runtime: false},
106106
{:dialyxir, "~> 1.3", only: [:dev, :test], runtime: false},
107-
{:ethereumex, "~> 0.10.6"},
107+
{:ethereumex, "~> 0.10 and >= 0.10.7"},
108108
{:ex_abi, "~> 0.8.0", optional: System.get_env("SKIP_EX_KECCAK") == "true"},
109109
{:ex_doc, "~> 0.32", only: :dev, runtime: false},
110110
{:ex_keccak, "~> 0.7.5"},

mix.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"dialyxir": {:hex, :dialyxir, "1.4.5", "ca1571ac18e0f88d4ab245f0b60fa31ff1b12cbae2b11bd25d207f865e8ae78a", [:mix], [{:erlex, ">= 0.2.7", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "b0fb08bb8107c750db5c0b324fa2df5ceaa0f9307690ee3c1f6ba5b9eb5d35c3"},
66
"earmark_parser": {:hex, :earmark_parser, "1.4.42", "f23d856f41919f17cd06a493923a722d87a2d684f143a1e663c04a2b93100682", [:mix], [], "hexpm", "6915b6ca369b5f7346636a2f41c6a6d78b5af419d61a611079189233358b8b8b"},
77
"erlex": {:hex, :erlex, "0.2.7", "810e8725f96ab74d17aac676e748627a07bc87eb950d2b83acd29dc047a30595", [:mix], [], "hexpm", "3ed95f79d1a844c3f6bf0cea61e0d5612a42ce56da9c03f01df538685365efb0"},
8-
"ethereumex": {:hex, :ethereumex, "0.10.6", "6d75cac39b5b7a720b064fe48563f205d3d9784e5bde25f983dd07cf306c2a6d", [:make, :mix], [{:finch, "~> 0.16", [hex: :finch, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "58cf926239dabf8bd1fc6cf50a37b926274240b7f58ba5b235a20b5500a9a7e1"},
8+
"ethereumex": {:hex, :ethereumex, "0.10.7", "b52c09f078a94f21aad13263ca1c031ce8505163762bd9e2c07167ab0c31e9be", [:make, :mix], [{:finch, "~> 0.16", [hex: :finch, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "f033fa1a619202904977b0399151977ed94649a44b9b8ac704ba8084c8647c54"},
99
"ex_abi": {:hex, :ex_abi, "0.8.1", "451fa960ddc4dfbb350e13509f3dd64ca586b8484a77aad9f7d778161b5eab79", [:mix], [{:ex_keccak, "~> 0.7.5", [hex: :ex_keccak, repo: "hexpm", optional: true]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "abcf53d556c2948e5c1241340afd4a72cdf93ab6daef16fc200c16ca1183cdca"},
1010
"ex_doc": {:hex, :ex_doc, "0.36.1", "4197d034f93e0b89ec79fac56e226107824adcce8d2dd0a26f5ed3a95efc36b1", [:mix], [{:earmark_parser, "~> 1.4.42", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_c, ">= 0.1.0", [hex: :makeup_c, repo: "hexpm", optional: true]}, {:makeup_elixir, "~> 0.14 or ~> 1.0", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1 or ~> 1.0", [hex: :makeup_erlang, repo: "hexpm", optional: false]}, {:makeup_html, ">= 0.1.0", [hex: :makeup_html, repo: "hexpm", optional: true]}], "hexpm", "d7d26a7cf965dacadcd48f9fa7b5953d7d0cfa3b44fa7a65514427da44eafd89"},
1111
"ex_keccak": {:hex, :ex_keccak, "0.7.6", "110c3ed76b55265975d9ae6628205b8a026f11fe081f3073e00c29aab2e91473", [:mix], [{:rustler, ">= 0.0.0", [hex: :rustler, repo: "hexpm", optional: true]}, {:rustler_precompiled, "~> 0.8", [hex: :rustler_precompiled, repo: "hexpm", optional: false]}], "hexpm", "9d1568424eb7b995e480d1b7f0c1e914226ee625496600abb922bba6f5cdc5e4"},
@@ -14,7 +14,7 @@
1414
"excoveralls": {:hex, :excoveralls, "0.18.3", "bca47a24d69a3179951f51f1db6d3ed63bca9017f476fe520eb78602d45f7756", [:mix], [{:castore, "~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "746f404fcd09d5029f1b211739afb8fb8575d775b21f6a3908e7ce3e640724c6"},
1515
"file_system": {:hex, :file_system, "1.0.1", "79e8ceaddb0416f8b8cd02a0127bdbababe7bf4a23d2a395b983c1f8b3f73edd", [:mix], [], "hexpm", "4414d1f38863ddf9120720cd976fce5bdde8e91d8283353f0e31850fa89feb9e"},
1616
"finch": {:hex, :finch, "0.19.0", "c644641491ea854fc5c1bbaef36bfc764e3f08e7185e1f084e35e0672241b76d", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.6.2 or ~> 1.7", [hex: :mint, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.4 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 1.1", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "fc5324ce209125d1e2fa0fcd2634601c52a787aff1cd33ee833664a5af4ea2b6"},
17-
"hpax": {:hex, :hpax, "1.0.1", "c857057f89e8bd71d97d9042e009df2a42705d6d690d54eca84c8b29af0787b0", [:mix], [], "hexpm", "4e2d5a4f76ae1e3048f35ae7adb1641c36265510a2d4638157fbcb53dda38445"},
17+
"hpax": {:hex, :hpax, "1.0.2", "762df951b0c399ff67cc57c3995ec3cf46d696e41f0bba17da0518d94acd4aac", [:mix], [], "hexpm", "2f09b4c1074e0abd846747329eaa26d535be0eb3d189fa69d812bfb8bfefd32f"},
1818
"idna": {:hex, :idna, "6.1.1", "8a63070e9f7d0c62eb9d9fcb360a7de382448200fbbd1b106cc96d3d8099df8d", [:rebar3], [{:unicode_util_compat, "~> 0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "92376eb7894412ed19ac475e4a86f7b413c1b9fbb5bd16dccd57934157944cea"},
1919
"jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"},
2020
"makeup": {:hex, :makeup, "1.2.1", "e90ac1c65589ef354378def3ba19d401e739ee7ee06fb47f94c687016e3713d1", [:mix], [{:nimble_parsec, "~> 1.4", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "d36484867b0bae0fea568d10131197a4c2e47056a6fbe84922bf6ba71c8d17ce"},

test/ethers_test.exs

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,17 @@ defmodule EthersTest do
4343
end
4444
end
4545

46+
describe "blob_base_fee" do
47+
test "returns the correct blob base fee" do
48+
assert {:ok, blob_base_fee} = Ethers.blob_base_fee()
49+
assert is_integer(blob_base_fee)
50+
end
51+
52+
test "bang version returns unwrapped value" do
53+
assert is_integer(Ethers.blob_base_fee!())
54+
end
55+
end
56+
4657
describe "current_block_number" do
4758
test "returns the current block number" do
4859
assert {:ok, n} = Ethers.current_block_number()
@@ -570,6 +581,73 @@ defmodule EthersTest do
570581
type: "0x2"
571582
}
572583
end
584+
585+
test "works with all transaction types" do
586+
types = [
587+
Ethers.Transaction.Legacy,
588+
Ethers.Transaction.Eip1559,
589+
Ethers.Transaction.Eip2930,
590+
Ethers.Transaction.Eip4844
591+
]
592+
593+
for type <- types do
594+
assert {:ok, _tx_hash} =
595+
Ethers.send_transaction(
596+
%{value: 1000},
597+
rpc_client: Ethers.TestRPCModule,
598+
from: @from,
599+
type: type,
600+
to: "0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc",
601+
rpc_opts: [send_params_to_pid: self()]
602+
)
603+
604+
type_id = Ethers.Utils.integer_to_hex(type.type_id())
605+
606+
assert_receive %{
607+
from: @from,
608+
to: "0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc",
609+
value: "0x3E8",
610+
type: ^type_id
611+
}
612+
end
613+
end
614+
615+
test "works with all transaction types and local signer" do
616+
types = [
617+
Ethers.Transaction.Legacy,
618+
Ethers.Transaction.Eip1559,
619+
Ethers.Transaction.Eip2930
620+
# Does not work with Anvil without sidecar
621+
# Ethers.Transaction.Eip4844
622+
]
623+
624+
for type <- types do
625+
assert {:ok, tx_hash} =
626+
Ethers.send_transaction(
627+
%{value: 1000},
628+
from: @from,
629+
type: type,
630+
to: "0x9965507D1a55bcC2695C58ba16FB37d819B0A4da",
631+
signer: Ethers.Signer.Local,
632+
blob_versioned_hashes: [
633+
Ethers.Utils.hex_decode!(
634+
"0x01bb9dc6ee48ae6a6f7ffd69a75196a4d49723beedf35981106e8da0efd8f796"
635+
)
636+
],
637+
access_list: access_list_fixture(),
638+
signer_opts: [
639+
private_key: @from_private_key
640+
]
641+
)
642+
643+
wait_for_transaction!(tx_hash)
644+
645+
type_id = Ethers.Utils.integer_to_hex(type.type_id())
646+
647+
assert %Ethers.Transaction.Signed{payload: %^type{}} = Ethers.get_transaction!(tx_hash)
648+
assert Ethers.get_transaction_receipt!(tx_hash)["type"] == type_id
649+
end
650+
end
573651
end
574652

575653
describe "sign_transaction/2" do
@@ -740,4 +818,43 @@ defmodule EthersTest do
740818
assert Ethers.chain_id!() == 31_337
741819
end
742820
end
821+
822+
defp access_list_fixture do
823+
[
824+
[
825+
<<7, 166, 233, 85, 186, 67, 69, 186, 232, 58, 194, 166, 250, 167, 113, 253, 221, 138, 32,
826+
17>>,
827+
[
828+
<<0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
829+
0, 0, 0>>,
830+
<<0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
831+
0, 0, 1>>,
832+
<<0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
833+
0, 0, 8>>
834+
]
835+
],
836+
[
837+
<<125, 26, 250, 123, 113, 143, 184, 147, 219, 48, 163, 171, 192, 207, 198, 8, 170, 207,
838+
235, 176>>,
839+
[
840+
<<20, 213, 49, 41, 66, 36, 14, 86, 92, 86, 174, 193, 24, 6, 206, 88, 227, 192, 227, 140,
841+
150, 38, 157, 117, 156, 93, 53, 162, 162, 228, 164, 73>>,
842+
<<39, 1, 253, 11, 38, 56, 243, 61, 178, 37, 217, 28, 106, 219, 218, 212, 101, 144, 168,
843+
106, 9, 162, 178, 195, 134, 64, 92, 47, 116, 42, 248, 66>>,
844+
<<55, 176, 184, 46, 229, 216, 168, 134, 114, 223, 56, 149, 164, 106, 244, 139, 188, 211,
845+
13, 110, 252, 201, 8, 19, 110, 41, 69, 111, 163, 6, 4, 187>>
846+
]
847+
],
848+
[
849+
<<160, 184, 105, 145, 198, 33, 139, 54, 193, 209, 157, 74, 46, 158, 176, 206, 54, 6, 235,
850+
72>>,
851+
[
852+
<<55, 87, 12, 241, 140, 109, 149, 116, 74, 21, 79, 162, 177, 155, 126, 149, 140, 120,
853+
239, 104, 184, 198, 10, 128, 220, 82, 127, 193, 94, 44, 235, 143>>,
854+
<<110, 137, 211, 30, 63, 216, 210, 191, 11, 65, 28, 69, 142, 152, 199, 70, 59, 247, 35,
855+
135, 140, 60, 232, 168, 69, 188, 249, 220, 59, 46, 57, 23>>
856+
]
857+
]
858+
]
859+
end
743860
end

test/support/test_rpc_module.ex

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,14 @@ defmodule Ethers.TestRPCModule do
1515
{:ok, opts[:tx_hash] || "tx_hash"}
1616
end
1717

18+
def eth_send_raw_transaction(params, opts) do
19+
if pid = opts[:send_params_to_pid] do
20+
send(pid, params)
21+
end
22+
23+
{:ok, opts[:tx_hash] || "tx_hash"}
24+
end
25+
1826
def eth_call(params, block, opts) do
1927
if pid = opts[:send_back_to_pid] do
2028
send(pid, :eth_call)

0 commit comments

Comments
 (0)