Ethers — A first-class Ethereum Web3 library for Elixir

Hey there, blockchain and Elixir enthusiasts!

Ever found yourself fumbling around with Ethereum and Elixir, trying to make them work together like two puzzle pieces that just don’t seem to fit? Well, I’ve got some great news for you! Introducing Elixir Ethers, an Ethereum Web3 library designed specifically for Elixir developers. It’s like we’ve finally found that missing puzzle piece!

AI Generated Elixir and Ethereum banner

Read on Medium

Ethers (github.com/alisinabh/elixir_ethers) is a user-friendly and comprehensive library that takes the headache out of interacting with the Ethereum blockchain. Inspired by the popular ethers.js library, Elixir Ethers seamlessly integrates with Elixir, making it feel like Ethereum was always meant to be part of the Elixir ecosystem.

But wait… Why Elixir with Ethereum?

That’s a great question. Elixir offers several advantages that make it well-suited for blockchain development and interacting with Ethereum:

  1. Concurrency: Elixir’s strong concurrency support, thanks to the Erlang virtual machine (BEAM), is perfect for handling distributed systems like blockchain networks.

  2. Fault-tolerance: In the world of blockchain, the stakes are often high (pun intended). Elixir’s fault-tolerant nature helps your application recover from unexpected issues and ensures reliable operation when dealing with valuable assets like cryptocurrencies.

  3. Scalability: Elixir enables you to easily scale your decentralized applications to keep up with the growing blockchain ecosystem.

  4. Functional programming: Elixir’s functional programming paradigm encourages cleaner and more predictable code, essential for blockchain transactions and smart contract interactions.

  5. Developer productivity: Elixir’s expressive syntax and powerful metaprogramming capabilities allow for faster development and easier debugging.

Now that you know why Elixir is a great fit for blockchain development, let’s dive into the Elixir Ethers library and explore how it can streamline your Ethereum development journey!

Getting Started

First, let’s create a new Elixir project to interact with the blockchain.

> mix new my_ethers_project
* creating README.md
* creating .formatter.exs
* creating .gitignore
* creating mix.exs
* creating lib
* creating lib/my_ethers_project.ex
* creating test
* creating test/test_helper.exs
* creating test/my_ethers_project_test.exs

Your Mix project was created successfully.
You can use "mix" to compile it, test it, and more:

    cd my_ethers_project
    mix test

Run "mix help" for more commands.

Then we need to add ethers and ethereumex in our mix.exs deps function.

defp deps do
  [
    {:ethers, "~> 0.0.1"}
  ]
end

Then create a config/config.exs file and add these two lines to it.. It will make Ethers use Cloudflare’s Etherum JSON-RPC server. (You should replace this later with your geth server url to be able to sign and send transactions.)

import Config

config :ethereumex, url: "https://cloudflare-eth.com/v1/mainnet"

To interact with a smart-contract, All you need is the ABI (Application Binary Interface) of the contract. Luckily getting the ABI for contracts is very easy. Just head to etherscan.io and search for the contract you want. For this example, lets use Wrapped Ethereum (WETH) contract. WETH is a ERC20 token which wraps ETH to be used as ERC-20 token.

WETH contract ABI on etherscan.ioWETH contract ABI on etherscan.io

Simply copy this JSON and save it to priv/weth-abi.json in our project root. Then we should add a module which will use ethers to implement all weth functions in compile-time for us like this in lib/my_ethers_project/weth.ex

defmodule MyEthersProject.WETH do
  @moduledoc """
  Wrapped Ethereum (WETH) Contract
  """

  use Ethers.Contract,
    abi_file: Path.join(:code.priv_dir(:my_ethers_project), "weth-abi.json"),
    default_address: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"
end

All Done! We can now download the dependencies and compile the app. Simply run mix deps.get and then iex -S mix to run your app in an interactive Elixir shell. Now let’s see what we have.

iex(4)> MyEthersProject.WETH.[PRESS TAB]
EventFilters       allowance/2        allowance/3        approve/2
approve/3          balance_of/1       balance_of/2       constructor/0
decimals/0         decimals/1         deposit/0          deposit/1
name/0             name/1             symbol/0           symbol/1
total_supply/0     total_supply/1     transfer/2         transfer/3
transfer_from/3    transfer_from/4    withdraw/1         withdraw/2

Wow, we see all the functions that is available in WETH contract. Let’s try one of them. For example name()

iex(1)> MyEthersProject.WETH.name
{:ok, ["Wrapped Ether"]}

Awesome, We have just called a function on the blockchain from our Elixir app just like calling any other function in Elixir.

How about documentation?

Rest assured that Ethers got you covered on documentation too. Ethers will generates documentation for every function and event filter it creates. You can see the docs through IEx, ExDocs or your Editors LSP. This significantly helps since you will not need to revisit ABI’s or contract source code as often during development.

Let’s see the documentation of balanceOf function in WETH contract.

iex(3)> h MyEthersProject.WETH.balance_of

                     def balance_of(owner, overrides \\ [])

  @spec balance_of(Ethers.Types.t_address(), Keyword.t()) ::
          {:ok, [non_neg_integer()]}
          | {:ok, Ethers.Types.t_hash()}
          | {:ok, Ethers.Contract.t_function_output()}

Executes balanceOf(address _owner) on the contract.

## Parameters

   _owner: `:address`
   overrides: Overrides and options for the call.
     to: The address of the recipient contract. (Required)
     action: Type of action for this function (:call, :send or
      prepare) Default: :call.
     rpc_opts: Options to pass to the RCP client e.g. :url.


## Return Types

   {:uint, 256}

What else can it do?

Right now Ethers is also capable of getting logs (Events) from the blockchain using the EventFilters it generates from contract ABIs. For example try running h MyEthersProject.WETH.EventFilters.deposit to see the documentation of the filter. Then use Ethers.get_logs to get those events.

Please visit our Hexdocs (hexdocs.pm/ethers) page for more documentation.

The plan is to make Ethers a feature rich library for interacting with EVM compatible blockchains. Some features worth mentioning are:

  • Ability to sign transactions directly in Ethers instead of relying on the RPC server accounts.

  • Listening to Events from the blockchain instead of polling.

  • Make Ethers module feature rich with implementing common functions like eth_getBalnce.

  • Implementing common contract protocols like Uniswap either as built-ins or in a separate repo.

Thank you for taking the time to read this post and trying Ethers. Like any other open-source project, Ethers needs your support as a community to continue delivering and improving. Please feel absolutely free to file issues or suggest/submit your changes through Ethers Github at github.com/alisinabh/elixir_ethers

Written on April 30, 2023