Ethereumex

repository·master·Indexed 19 days ago

https://github.com/mana-ethereum/ethereumex

An Elixir JSON-RPC client for interacting with the Ethereum blockchain. It supports multiple transport protocols including HTTP, IPC, and WebSockets for both standard RPC calls and real-time subscriptions (such as :newHeads, :logs, and :newPendingTransactions). The library maps standard camelCase JSON-RPC methods to snake_case Elixir functions and provides support for batch requests, custom JSON modules, and telemetry monitoring.

Tokens
6K
Snippets
22
Records
28
Agent score
64%

What's inside ethereumex

  1. Use Ethereumex with IPC instead of HTTP

    master

    If your Ethereum node supports IPC (Inter-Process Communication), you can use Ethereumex.IpcClient instead of Ethereumex.HttpClient. All method signatures and usage patterns remain identical, allowing you to switch transport layers easily.

    iex> Ethereumex.IpcClient.web3_client_version
  2. Handle WebSocket subscription notifications

    master

    When a subscription event occurs, a message is sent to your process. The message follows this structure:

    %{
      "method" => "eth_subscription",
      "params" => %{
        "subscription" => subscription_id,
        "result" => result
      }
    }
    receive do
      %{
        "method" => "eth_subscription",
        "params" => %{
          "subscription" => subscription_id,
          "result" => result
        }
      } -> handle_notification(result)
    end
  3. Subscribe to blockchain events via WebSocket

    master

    The WebSocket client supports real-time subscriptions. Use Ethereumex.WebsocketClient.subscribe/2 with one of the following types:

    • :newHeads: New block headers.
    • :logs: Contract events/logs (requires a filter map).
    • :newPendingTransactions: Pending transaction hashes.

    To stop receiving updates, use Ethereumex.WebsocketClient.unsubscribe(subscription_id).

    # Subscribe to new block headers
    {:ok, subscription_id} = Ethereumex.WebsocketClient.subscribe(:newHeads)
    
    # Subscribe to logs/events from specific contracts
    filter = %{
      address: "0x8320fe7702b96808f7bbc0d4a888ed1468216cfd",
      topics: ["0xd78a0cb8bb633d06981248b816e7bd33c2a35a6089241d099fa519e361cab902"]
    }
    {:ok, subscription_id} = Ethereumex.WebsocketClient.subscribe(:logs, filter)
    
    # Subscribe to pending transactions
    {:ok, subscription_id} = Ethereumex.WebsocketClient.subscribe(:newPendingTransactions)
    
    # Unsubscribe when done
    Ethereumex.WebsocketClient.unsubscribe(subscription_id)
  4. Execute smart contract calls with eth_call

    master

    To perform read-only smart contract calls, use the eth_call/1 method. You must provide a data field containing the ABI-encoded method signature and arguments, and a to field containing the contract address.

    Note: The data string must be hex-encoded and typically prefixed with 0x. The contract address should be provided as a string.

    It is recommended to use a library like ex_abi to handle the encoding of method signatures and arguments.

    defp deps do
      [
        {:ethereumex, "~> 0.9"},
        {:ex_abi, "~> 0.5"}
      ]
    end
    
    # Example: Calling balanceOf(address)
    address           = "0xF742d4cE7713c54dD701AA9e92101aC42D63F895" |> String.slice(2..-1) |> Base.decode16!(case: :mixed)
    contract_address  = "0xC28980830dD8b9c68a45384f5489ccdAF19D53cC"
    abi_encoded_data  = ABI.encode("balanceOf(address)", [address]) |> Base.encode16(case: :lower)
    
    balance_bytes = Ethereumex.HttpClient.eth_call(%{
      data: "0x" <> abi_encoded_data,
      to: contract_address
    })
  5. Configure IPC client settings

    master

    To use IPC, set client_type to :ipc and provide the ipc_path. You can also tune the IPC worker pool size and request timeouts.

    config :ethereumex,
      client_type: :ipc,
      ipc_path: "/path/to/ipc",
      ipc_worker_size: 5,
      ipc_max_worker_overflow: 2,
      ipc_request_timeout: 60_000
  6. Use Ethereumex.Client.BaseClient via __using__

    master

    The Ethereumex.Client.BaseClient module provides a macro __using__ that can be included in different client implementations (such as HTTP or IPC clients). When you include this macro, your module will implement the Ethereumex.Client.Behaviour and gain access to a wide range of Ethereum JSON-RPC methods.

    All methods in the BaseClient accept an optional opts argument (a keyword list) to pass additional configuration to the underlying request mechanism.

    defmodule MyCustomClient do
      use Ethereumex.Client.BaseClient
      # Your implementation of post_request/2 goes here
    end
  7. Handle subscription notifications in your process

    master

    When a subscription event occurs, the notification is sent to your process as a message. The message follows the eth_subscription method format.

    # Example of receiving a notification in a process loop
    receive do
      %{
        "method" => "eth_subscription",
        "params" => %{
          "subscription" => "0x9cef478923ff08bf67fde6c64013158d",
          "result" => %{"number" => "0x1b4", ...}
        }
      } -> :ok
    end
  8. Configure WebSocket client settings

    master

    To use the WebSocket client for standard RPC calls and real-time subscriptions, set client_type to :websocket and provide the websocket_url.

    config :ethereumex,
      websocket_url: "ws://localhost:8545",
      client_type: :websocket
  9. Configure HTTP client settings

    master

    To use the HTTP client, specify the url in your configuration. You can also configure connection pool timeouts and HTTP headers via http_options and http_headers.

    config :ethereumex,
      url: "http://localhost:8545"
    
    config :ethereumex,
      http_options: [pool_timeout: 5000, receive_timeout: 15_000],
      http_headers: [{"Content-Type", "application/json"}]
  10. Run OpenEthereum via Docker Compose

    master

    You can deploy an OpenEthereum instance using the provided docker-compose.yml configuration. This setup exposes the JSON-RPC interfaces and maps a local directory to the container's data directory for persistence.

    version: '3.8'
    
    services:
      openethereum:
        image: openethereum/openethereum:v3.3.0
        command: '--chain=dev --unlock=0x00a329c0648769a73afac7f9381e08fb43dbea72 --password=/home/openethereum/.local/share/openethereum/passfile --jsonrpc-interface=0.0.0.0'
        ports:
          - '8545:8545'
          - '8546:8546'
        volumes:
          - ./docker:/home/openethereum/.local/share