View Source Signet.RPC (Signet v0.2.0-alpha4)

Excessively simple RPC client for Ethereum.

Summary

Functions

RPC call to call a transaction and preview results.

RPC call to call to estimate gas used by a given call.

Helper function to work with other Signet modules to get a nonce, sign a transction, and transmit it to the network.

RPC call to call to get the current gas price.

RPC call to get account nonce.

RPC call to get a transaction receipt

Simple RPC client for a JSON-RPC Ethereum node.

RPC call to send a raw transaction.

RPC call to get a transaction receipt

Functions

Link to this function

call_trx(trx, opts \\ [])

View Source

RPC call to call a transaction and preview results.

Examples

iex> Signet.Transaction.V1.new(1, {100, :gwei}, 100_000, <<1::160>>, {2, :wei}, <<1, 2, 3>>)
iex> |> Signet.RPC.call_trx()
{:ok, <<0x0c>>}

iex> Signet.Transaction.V1.new(1, {100, :gwei}, 100_000, <<1::160>>, {2, :wei}, <<1, 2, 3>>)
iex> |> Signet.RPC.call_trx(decode: :hex_unsigned)
{:ok, 0x0c}

iex> Signet.Transaction.V1.new(1, {100, :gwei}, 100_000, <<10::160>>, {2, :wei}, <<1, 2, 3>>)
iex> |> Signet.RPC.call_trx()
{:error, "error 3: execution reverted (0x3d738b2e)"}

iex> errors = ["Unauthorized()", "BadNonce()", "NotEnoughSigners()", "NotActiveWithdrawalAddress()", "NotActiveOperator()", "DuplicateSigners()"]
iex> Signet.Transaction.V1.new(1, {100, :gwei}, 100_000, <<10::160>>, {2, :wei}, <<1, 2, 3>>)
iex> |> Signet.RPC.call_trx(errors: errors)
{:error, "error 3: execution reverted (NotActiveOperator()[])"}

iex> errors = ["Cool(uint256,string)"]
iex> Signet.Transaction.V1.new(1, {100, :gwei}, 100_000, <<11::160>>, {2, :wei}, <<1, 2, 3>>)
iex> |> Signet.RPC.call_trx(errors: errors)
{:error, "error 3: execution reverted (Cool(uint256,string)[1, \"cat\"])"}
Link to this function

estimate_gas(trx, opts \\ [])

View Source

RPC call to call to estimate gas used by a given call.

Examples

iex> Signet.Transaction.V1.new(1, {100, :gwei}, 100_000, <<1::160>>, {2, :wei}, <<1, 2, 3>>)
iex> |> Signet.RPC.estimate_gas()
{:ok, 0x0d}
Link to this function

execute_trx(contract, call_data, opts \\ [])

View Source

Helper function to work with other Signet modules to get a nonce, sign a transction, and transmit it to the network.

If you need higher-level functionality, like manual nonce tracking, you may want to use the more granular function calls.

Options:

  • gas_price - Set the base gas for the transaction, overrides all other gas prices listed below (default nil)
  • base_fee - Set the base price for the transaction, if nil, will use base gas price from eth_gasPrice call (default nil)
  • base_fee_buffer - Buffer for the gas price when estimating gas (default: 1.2 = 120%)
  • priority_fee - Additional gas to send as a priority fee. (default: {0, :gwei})
  • gas_limit - Set the gas limit for the transaction (default: calls eth_estimateGas)
  • gas_buffer - Buffer if estimating gas limit (default: 1.5 = 150%)
  • value - Value to provide with transaction in wei (default: 0)
  • nonce - Nonce to send with transaction. (default: lookup via eth_transactionCount)
  • verify - Verify the function is likely to succeed before submitting (default: true)

Note: if we don't verify, then estimateGas will likely fail if the transaction were to fail.

    To prevent this, `gas_limit` should always be supplied when `verify` is set to false.

Note: Currently Signet uses pre-EIP-1559 signatures and thus gas prices are not broken out by

    base fee and priority fee.

Examples

iex> signer_proc = Signet.Test.Signer.start_signer()
iex> {:ok, trx_id} = Signet.RPC.execute_trx(<<1::160>>, {"baz(uint,address)", [50, :binary.decode_unsigned(<<1::160>>)]}, gas_price: {50, :gwei}, value: 0, signer: signer_proc)
iex> <<nonce::integer-size(8), gas_price::integer-size(64), gas_limit::integer-size(24), to::binary>> = trx_id
iex> {nonce, gas_price, gas_limit, to}
{4, 50000000000, 20, <<1::160>>}

iex> signer_proc = Signet.Test.Signer.start_signer()
iex> {:ok, trx_id} = Signet.RPC.execute_trx(<<1::160>>, {"baz(uint,address)", [50, <<1::160>> |> :binary.decode_unsigned]}, gas_price: {50, :gwei}, gas_limit: 100_000, value: 0, signer: signer_proc)
iex> <<nonce::integer-size(8), gas_price::integer-size(64), gas_limit::integer-size(24), to::binary>> = trx_id
iex> {nonce, gas_price, gas_limit, to}
{4, 50000000000, 100000, <<1::160>>}

iex> signer_proc = Signet.Test.Signer.start_signer()
iex> {:ok, trx_id} = Signet.RPC.execute_trx(<<1::160>>, {"baz(uint,address)", [50, <<1::160>> |> :binary.decode_unsigned]}, gas_price: {50, :gwei}, gas_limit: 100_000, value: 0, nonce: 10, signer: signer_proc)
iex> <<nonce::integer-size(8), gas_price::integer-size(64), gas_limit::integer-size(24), to::binary>> = trx_id
iex> {nonce, gas_price, gas_limit, to}
{10, 50000000000, 100000, <<1::160>>}

iex> signer_proc = Signet.Test.Signer.start_signer()
iex> Signet.RPC.execute_trx(<<10::160>>, {"baz(uint,address)", [50, <<1::160>> |> :binary.decode_unsigned]}, gas_price: {50, :gwei}, gas_limit: 100_000, value: 0, nonce: 10, signer: signer_proc)
{:error, "error 3: execution reverted (0x3d738b2e)"}

iex> # Set gas price directly
iex> signer_proc = Signet.Test.Signer.start_signer()
iex> {:ok, trx_id} = Signet.RPC.execute_trx(<<10::160>>, {"baz(uint,address)", [50, <<1::160>> |> :binary.decode_unsigned]}, gas_price: {50, :gwei}, gas_limit: 100_000, value: 0, nonce: 10, verify: false, signer: signer_proc)
iex> <<nonce::integer-size(8), gas_price::integer-size(64), gas_limit::integer-size(24), to::binary>> = trx_id
iex> {nonce, gas_price, gas_limit, to}
{10, 50000000000, 100000, <<10::160>>}

iex> # Default gas price
iex> signer_proc = Signet.Test.Signer.start_signer()
iex> {:ok, trx_id} = Signet.RPC.execute_trx(<<10::160>>, {"baz(uint,address)", [50, <<1::160>> |> :binary.decode_unsigned]}, gas_limit: 100_000, value: 0, nonce: 10, verify: false, signer: signer_proc)
iex> <<nonce::integer-size(8), gas_price::integer-size(64), gas_limit::integer-size(24), to::binary>> = trx_id
iex> {nonce, gas_price, gas_limit, to}
{10, 1200000000, 100000, <<10::160>>}

iex> # Set priority fee
iex> signer_proc = Signet.Test.Signer.start_signer()
iex> {:ok, trx_id} = Signet.RPC.execute_trx(<<10::160>>, {"baz(uint,address)", [50, <<1::160>> |> :binary.decode_unsigned]}, priority_fee: {3, :gwei}, gas_limit: 100_000, value: 0, nonce: 10, verify: false, signer: signer_proc)
iex> <<nonce::integer-size(8), gas_price::integer-size(64), gas_limit::integer-size(24), to::binary>> = trx_id
iex> {nonce, gas_price, gas_limit, to}
{10, 4200000000, 100000, <<10::160>>}

iex> # Set base fee and priority fee
iex> signer_proc = Signet.Test.Signer.start_signer()
iex> {:ok, trx_id} = Signet.RPC.execute_trx(<<10::160>>, {"baz(uint,address)", [50, <<1::160>> |> :binary.decode_unsigned]}, base_fee: {1, :gwei}, priority_fee: {3, :gwei}, gas_limit: 100_000, value: 0, nonce: 10, verify: false, signer: signer_proc)
iex> <<nonce::integer-size(8), gas_price::integer-size(64), gas_limit::integer-size(24), to::binary>> = trx_id
iex> {nonce, gas_price, gas_limit, to}
{10, 4000000000, 100000, <<10::160>>}

RPC call to call to get the current gas price.

Examples

iex> Signet.RPC.gas_price()
{:ok, 1000000000}
Link to this function

get_nonce(account, opts \\ [])

View Source

RPC call to get account nonce.

Examples

iex> Signet.RPC.get_nonce(Signet.Util.decode_hex!("0x407d73d8a49eeb85d32cf465507dd71d507100c1"))
{:ok, 4}
Link to this function

get_trx_receipt(trx_id, opts \\ [])

View Source

RPC call to get a transaction receipt

Examples

iex> Signet.RPC.get_trx_receipt(<<0::256>>)
{:ok,
  %Signet.Receipt{
    transaction_hash: Signet.Util.decode_hex!("0x85d995eba9763907fdf35cd2034144dd9d53ce32cbec21349d4b12823c6860c5"),
    transaction_index: 0x66,
    block_hash: Signet.Util.decode_hex!("0xa957d47df264a31badc3ae823e10ac1d444b098d9b73d204c40426e57f47e8c3"),
    block_number: 0xeff35f,
    from: Signet.Util.decode_hex!("0x6221a9c005f6e47eb398fd867784cacfdcfff4e7"),
    to: Signet.Util.decode_hex!("0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"),
    cumulative_gas_used: 0xa12515,
    effective_gas_price: 0x5a9c688d4,
    gas_used: 0xb4c8,
    contract_address: nil,
    logs: [
      %Signet.Receipt.Log{
        log_index: 1,
        block_number: 0x01b4,
        block_hash: Signet.Util.decode_hex!("0xaa8216c5785ac562ff41e2dcfdf5785ac562ff41e2dcfdf829c5a142f1fccd7d"),
        transaction_hash: Signet.Util.decode_hex!("0xaadf829c5a142f1fccd7d8216c5785ac562ff41e2dcfdf5785ac562ff41e2dcf"),
        transaction_index: 0,
        address: Signet.Util.decode_hex!("0x16c5785ac562ff41e2dcfdf829c5a142f1fccd7d"),
        data: Signet.Util.decode_hex!("0x0000000000000000000000000000000000000000000000000000000000000000"),
        topics: [
          Signet.Util.decode_hex!("0x59ebeb90bc63057b6515673c3ecf9438e5058bca0f92585014eced636878c9a5")
        ]
      }
    ],
    logs_bloom: Signet.Util.decode_hex!("0x0000000000000000000000000000000000000000000000000000000000000001"),
    type: 0x02,
    status: 0x01,
  }
}

iex> Signet.RPC.get_trx_receipt("0x85d995eba9763907fdf35cd2034144dd9d53ce32cbec21349d4b12823c6860c5")
{:ok,
  %Signet.Receipt{
    transaction_hash: Signet.Util.decode_hex!("0x85d995eba9763907fdf35cd2034144dd9d53ce32cbec21349d4b12823c6860c5"),
    transaction_index: 0x66,
    block_hash: Signet.Util.decode_hex!("0xa957d47df264a31badc3ae823e10ac1d444b098d9b73d204c40426e57f47e8c3"),
    block_number: 0xeff35f,
    from: Signet.Util.decode_hex!("0x6221a9c005f6e47eb398fd867784cacfdcfff4e7"),
    to: Signet.Util.decode_hex!("0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"),
    cumulative_gas_used: 0xa12515,
    effective_gas_price: 0x5a9c688d4,
    gas_used: 0xb4c8,
    contract_address: nil,
    logs: [
      %Signet.Receipt.Log{
        log_index: 1,
        block_number: 0x01b4,
        block_hash: Signet.Util.decode_hex!("0xaa8216c5785ac562ff41e2dcfdf5785ac562ff41e2dcfdf829c5a142f1fccd7d"),
        transaction_hash: Signet.Util.decode_hex!("0xaadf829c5a142f1fccd7d8216c5785ac562ff41e2dcfdf5785ac562ff41e2dcf"),
        transaction_index: 0,
        address: Signet.Util.decode_hex!("0x16c5785ac562ff41e2dcfdf829c5a142f1fccd7d"),
        data: Signet.Util.decode_hex!("0x0000000000000000000000000000000000000000000000000000000000000000"),
        topics: [
          Signet.Util.decode_hex!("0x59ebeb90bc63057b6515673c3ecf9438e5058bca0f92585014eced636878c9a5")
        ]
      }
    ],
    logs_bloom: Signet.Util.decode_hex!("0x0000000000000000000000000000000000000000000000000000000000000001"),
    type: 0x02,
    status: 0x01,
  }
}

iex> Signet.RPC.get_trx_receipt(<<1::256>>)
{:error, "failed to decode result"}
Link to this function

send_rpc(method, params, opts \\ [])

View Source

Simple RPC client for a JSON-RPC Ethereum node.

Examples

iex> Signet.RPC.send_rpc("net_version", [])
{:ok, "3"}

iex> Signet.RPC.send_rpc("get_balance", ["0x407d73d8a49eeb85d32cf465507dd71d507100c1", "latest"], ethereum_node: "http://example.com")
{:ok, "0x0234c8a3397aab58"}
Link to this function

send_trx(trx, opts \\ [])

View Source

RPC call to send a raw transaction.

Examples

iex> signer_proc = Signet.Test.Signer.start_signer()
iex> {:ok, signed_trx} = Signet.Transaction.build_signed_trx(<<1::160>>, 5, {"baz(uint,address)", [50, :binary.decode_unsigned(<<1::160>>)]}, {50, :gwei}, 100_000, 0, chain_id: :goerli, signer: signer_proc)
iex> {:ok, trx_id} = Signet.RPC.send_trx(signed_trx)
iex> <<nonce::integer-size(8), gas_price::integer-size(64), gas_limit::integer-size(24), to::binary>> = trx_id
iex> {nonce, gas_price, gas_limit, to}
{5, 50000000000, 100000, <<1::160>>}
Link to this function

trace_trx(trx_id, opts \\ [])

View Source

RPC call to get a transaction receipt

Examples

iex> Signet.RPC.trace_trx("0x85d995eba9763907fdf35cd2034144dd9d53ce32cbec21349d4b12823c6860c5")
{:ok,
  [
  %Signet.Trace{
    action: %Signet.Trace.Action{
      call_type: "call",
      from: Signet.Util.decode_hex!("0x83806d539d4ea1c140489a06660319c9a303f874"),
      gas: 0x01a1f8,
      input: <<>>,
      to: Signet.Util.decode_hex!("0x1c39ba39e4735cb65978d4db400ddd70a72dc750"),
      value: 0x7a16c911b4d00000,
    },
    block_hash: Signet.Util.decode_hex!("0x7eb25504e4c202cf3d62fd585d3e238f592c780cca82dacb2ed3cb5b38883add"),
    block_number: 3068185,
    gas_used: 0x2982,
    output: <<>>,
    subtraces: 2,
    trace_address: [Signet.Util.decode_hex!("0x1c39ba39e4735cb65978d4db400ddd70a72dc750")],
    transaction_hash: Signet.Util.decode_hex!("0x17104ac9d3312d8c136b7f44d4b8b47852618065ebfa534bd2d3b5ef218ca1f3"),
    transaction_position: 2,
    type: "call"
  },
  %Signet.Trace{
    action: %Signet.Trace.Action{
      call_type: "call",
      from: Signet.Util.decode_hex!("0x83806d539d4ea1c140489a06660319c9a303f874"),
      gas: 0x01a1f8,
      input: <<>>,
      to: Signet.Util.decode_hex!("0x1c39ba39e4735cb65978d4db400ddd70a72dc750"),
      value: 0x7a16c911b4d00000,
    },
    block_hash: Signet.Util.decode_hex!("0x7eb25504e4c202cf3d62fd585d3e238f592c780cca82dacb2ed3cb5b38883add"),
    block_number: 3068186,
    gas_used: 0x2982,
    output: <<>>,
    subtraces: 2,
    trace_address: [Signet.Util.decode_hex!("0x1c39ba39e4735cb65978d4db400ddd70a72dc750")],
    transaction_hash: Signet.Util.decode_hex!("0x17104ac9d3312d8c136b7f44d4b8b47852618065ebfa534bd2d3b5ef218ca1f3"),
    transaction_position: 2,
    type: "call"
  }
]}