Code Monkey home page Code Monkey logo

ethereumex's Introduction

Ethereumex

CircleCI Module Version Hex Docs Total Download License Last Updated

Elixir JSON-RPC client for the Ethereum blockchain.

Check out the documentation here.

Installation

Add :ethereumex to your list of dependencies in mix.exs:

def deps do
  [
    {:ethereumex, "~> 0.9"}
  ]
end

Ensure :ethereumex is started before your application:

def application do
  [
    applications: [:ethereumex]
  ]
end

Configuration

In config/config.exs, add Ethereum protocol host params to your config file

config :ethereumex,
  url: "http://localhost:8545"

You can also configure the HTTP request timeout for requests sent to the Ethereum JSON-RPC (you can also overwrite this configuration in opts used when calling the client).

config :ethereumex,
  http_options: [pool_timeout: 5000, receive_timeout: 15_000],
  http_headers: [{"Content-Type", "application/json"}]

:pool_timeout - This timeout is applied when we check out a connection from the pool. Default value is 5_000. :receive_timeout - The maximum time to wait for a response before returning an error. Default value is 15_000

If you want to use IPC you will need to set a few things in your config.

First, specify the :client_type:

config :ethereumex,
  client_type: :ipc

This will resolve to :http by default.

Second, specify the :ipc_path:

config :ethereumex,
  ipc_path: "/path/to/ipc"

If you want to count the number of RPC calls per RPC method or overall, you can attach yourself to executed telemetry events. There are two events you can attach yourself to: [:ethereumex] # has RPC method name in metadata Emitted event: {:event, [:ethereumex], %{counter: 1}, %{method_name: "method_name"}}

or more granular [:ethereumex, <rpc_method>] # %{} metadata Emitted event: {:event, [:ethereumex, :method_name_as_atom], %{counter: 1}, %{}}

Each event caries a single ticker that you can pass into your counters (like Statix.increment/2). Be sure to add :telemetry as project dependency.

The IPC client type mode opens a pool of connection workers (default is 5 and 2, respectively). You can configure the pool size.

config :ethereumex,
  ipc_worker_size: 5,
  ipc_max_worker_overflow: 2,
  ipc_request_timeout: 60_000

Test

Download parity and initialize the password file

$ make setup

Run parity

$ make run

Run tests

$ make test

Usage

Available methods:

IpcClient

You can follow along with any of these examples using IPC by replacing HttpClient with IpcClient.

Examples

iex> Ethereumex.HttpClient.web3_client_version
{:ok, "Parity//v1.7.2-beta-9f47909-20170918/x86_64-macos/rustc1.19.0"}

# Using the url option will overwrite the configuration
iex> Ethereumex.HttpClient.web3_client_version(url: "http://localhost:8545")
{:ok, "Parity//v1.7.2-beta-9f47909-20170918/x86_64-macos/rustc1.19.0"}

iex> Ethereumex.HttpClient.web3_sha3("wrong_param")
{:error, %{"code" => -32602, "message" => "Invalid params: invalid format."}}

iex> Ethereumex.HttpClient.eth_get_balance("0x407d73d8a49eeb85d32cf465507dd71d507100c1")
{:ok, "0x0"}

Note that all method names are snakecases, so, for example, shh_getMessages method has corresponding Ethereumex.HttpClient.shh_get_messages/1 method. Signatures can be found in Ethereumex.Client.Behaviour. There are more examples in tests.

eth_call example - Read only smart contract calls

In order to call a smart contract using the JSON-RPC interface you need to properly hash the data attribute (this will need to include the contract method signature along with arguments if any). You can do this manually or use a hex package like ABI to parse your smart contract interface or encode individual calls.

defp deps do
  [
    ...
    {:ethereumex, "~> 0.9"},
    {:ex_abi, "~> 0.5"}
    ...
  ]
end

Now load the ABI and pass the method signature. Note that the address needs to be converted to bytes:

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)

Now you can use eth_call to execute this smart contract command:

balance_bytes = Ethereumex.HttpClient.eth_call(%{
  data: "0x" <> abi_encoded_data,
  to: contract_address
})

To convert the balance into an integer:

balance_bytes
|> String.slice(2..-1)
|> Base.decode16!(case: :lower)
|> TypeDecoder.decode_raw([{:uint, 256}])
|> List.first

Custom requests

Many Ethereum protocol implementations support additional JSON-RPC API methods. To use them, you should call Ethereumex.HttpClient.request/3 method.

For example, let's call parity's personal_listAccounts method.

iex> Ethereumex.HttpClient.request("personal_listAccounts", [], [])
{:ok,
 ["0x71cf0b576a95c347078ec2339303d13024a26910",
  "0x7c12323a4fff6df1a25d38319d5692982f48ec2e"]}

Batch requests

To send batch requests use Ethereumex.HttpClient.batch_request/1 or Ethereumex.HttpClient.batch_request/2 method.

requests = [
   {:web3_client_version, []},
   {:net_version, []},
   {:web3_sha3, ["0x68656c6c6f20776f726c64"]}
 ]
 Ethereumex.HttpClient.batch_request(requests)
 {
   :ok,
   [
     {:ok, "Parity//v1.7.2-beta-9f47909-20170918/x86_64-macos/rustc1.19.0"},
     {:ok, "42"},
     {:ok, "0x47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad"}
   ]
 }

Built on Ethereumex

If you are curious what others are building with ethereumex, you might want to take a look at these projects:

  • exw3 - A high-level contract abstraction and other goodies similar to web3.js

  • eth - Ethereum utilities for Elixir.

  • eth_contract - A set of helper methods for calling ETH Smart Contracts via JSON RPC.

Contributing

  1. Fork it!
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request

Copyright and License

Copyright (c) 2018 Ayrat Badykov

Released under the MIT License, which can be found in the repository in LICENSE.md.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.