From 1f5ecc8e4f4a5faf0057ef3ea44fd6abf731725e Mon Sep 17 00:00:00 2001 From: hswick Date: Mon, 8 Oct 2018 23:39:53 -0500 Subject: [PATCH 1/5] Updated dependencies --- lib/exw3.ex | 2 +- mix.exs | 4 ++-- mix.lock | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/exw3.ex b/lib/exw3.ex index 546278e..221289d 100644 --- a/lib/exw3.ex +++ b/lib/exw3.ex @@ -259,7 +259,7 @@ defmodule ExW3 do file = File.read(Path.join(System.cwd(), file_path)) case file do - {:ok, abi} -> reformat_abi(Poison.Parser.parse!(abi)) + {:ok, abi} -> reformat_abi(Poison.Parser.parse!(abi, %{})) err -> err end end diff --git a/mix.exs b/mix.exs index 9af57e8..0d28992 100644 --- a/mix.exs +++ b/mix.exs @@ -35,9 +35,9 @@ defmodule ExW3.MixProject do defp deps do [ {:ex_doc, ">= 0.0.0", only: :dev}, - {:ethereumex, "~> 0.3.4"}, + {:ethereumex, "~> 0.4.0"}, {:abi, "~> 0.1.8"}, - {:poison, "~> 3.1"} + {:poison, "~> 4.0.1"} ] end diff --git a/mix.lock b/mix.lock index 968291b..d187407 100644 --- a/mix.lock +++ b/mix.lock @@ -3,11 +3,11 @@ "binary": {:hex, :binary, "0.0.5", "20d816f7274ea34f1b673b4cff2fdb9ebec9391a7a68c349070d515c66b1b2cf", [:mix], [], "hexpm"}, "certifi": {:hex, :certifi, "2.4.2", "75424ff0f3baaccfd34b1214184b6ef616d89e420b258bb0a5ea7d7bc628f7f0", [:rebar3], [{:parse_trans, "~>3.3", [hex: :parse_trans, repo: "hexpm", optional: false]}], "hexpm"}, "earmark": {:hex, :earmark, "1.2.6", "b6da42b3831458d3ecc57314dff3051b080b9b2be88c2e5aa41cd642a5b044ed", [:mix], [], "hexpm"}, - "ethereumex": {:hex, :ethereumex, "0.3.4", "5222472508bf7de46e06590e85da5d7fe49d33a386ecabc71c364c439a99945e", [:mix], [{:httpoison, "~> 1.1.0", [hex: :httpoison, repo: "hexpm", optional: false]}, {:poison, "~> 3.1.0", [hex: :poison, repo: "hexpm", optional: false]}], "hexpm"}, + "ethereumex": {:hex, :ethereumex, "0.4.0", "6ed98639c717dc7940a56f657fb81f44afe3e0287f9825b7b0f9016642e605ac", [:mix], [{:httpoison, "~> 1.3.1", [hex: :httpoison, repo: "hexpm", optional: false]}, {:poison, "~> 4.0.1", [hex: :poison, repo: "hexpm", optional: false]}], "hexpm"}, "ex_doc": {:hex, :ex_doc, "0.19.1", "519bb9c19526ca51d326c060cb1778d4a9056b190086a8c6c115828eaccea6cf", [:mix], [{:earmark, "~> 1.1", [hex: :earmark, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.7", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm"}, "exth_crypto": {:hex, :exth_crypto, "0.1.6", "8e636a9bcb75d8e32451be96e547a495121ed2178d078db294edb0f81f7cf2e8", [:mix], [{:binary, "~> 0.0.4", [hex: :binary, repo: "hexpm", optional: false]}, {:keccakf1600, "~> 2.0.0", [hex: :keccakf1600_orig, repo: "hexpm", optional: false]}, {:libsecp256k1, "~> 0.1.9", [hex: :libsecp256k1, repo: "hexpm", optional: false]}], "hexpm"}, - "hackney": {:hex, :hackney, "1.14.0", "66e29e78feba52176c3a4213d42b29bdc4baff93a18cfe480f73b04677139dee", [:rebar3], [{:certifi, "2.4.2", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "6.0.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.4", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"}, - "httpoison": {:hex, :httpoison, "1.1.1", "96ed7ab79f78a31081bb523eefec205fd2900a02cda6dbc2300e7a1226219566", [:mix], [{:hackney, "~> 1.8", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"}, + "hackney": {:hex, :hackney, "1.14.3", "b5f6f5dcc4f1fba340762738759209e21914516df6be440d85772542d4a5e412", [:rebar3], [{:certifi, "2.4.2", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "6.0.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.4", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"}, + "httpoison": {:hex, :httpoison, "1.3.1", "7ac607311f5f706b44e8b3fab736d0737f2f62a31910ccd9afe7227b43edb7f0", [:mix], [{:hackney, "~> 1.8", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"}, "idna": {:hex, :idna, "6.0.0", "689c46cbcdf3524c44d5f3dde8001f364cd7608a99556d8fbd8239a5798d4c10", [:rebar3], [{:unicode_util_compat, "0.4.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"}, "keccakf1600": {:hex, :keccakf1600_orig, "2.0.0", "0a7217ddb3ee8220d449bbf7575ec39d4e967099f220a91e3dfca4dbaef91963", [:rebar3], [], "hexpm"}, "libsecp256k1": {:hex, :libsecp256k1, "0.1.9", "e725f31364cda7b554d56ce2bb976241303dde5ffd1ad59598513297bf1f2af6", [:make, :mix], [{:mix_erlang_tasks, "0.1.0", [hex: :mix_erlang_tasks, repo: "hexpm", optional: false]}], "hexpm"}, @@ -18,7 +18,7 @@ "mix_erlang_tasks": {:hex, :mix_erlang_tasks, "0.1.0", "36819fec60b80689eb1380938675af215565a89320a9e29c72c70d97512e4649", [:mix], [], "hexpm"}, "nimble_parsec": {:hex, :nimble_parsec, "0.2.2", "d526b23bdceb04c7ad15b33c57c4526bf5f50aaa70c7c141b4b4624555c68259", [:mix], [], "hexpm"}, "parse_trans": {:hex, :parse_trans, "3.3.0", "09765507a3c7590a784615cfd421d101aec25098d50b89d7aa1d66646bc571c1", [:rebar3], [], "hexpm"}, - "poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], [], "hexpm"}, + "poison": {:hex, :poison, "4.0.1", "bcb755a16fac91cad79bfe9fc3585bb07b9331e50cfe3420a24bcc2d735709ae", [:mix], [], "hexpm"}, "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.4", "f0eafff810d2041e93f915ef59899c923f4568f4585904d010387ed74988e77b", [:make, :mix, :rebar3], [], "hexpm"}, "unicode_util_compat": {:hex, :unicode_util_compat, "0.4.1", "d869e4c68901dd9531385bb0c8c40444ebf624e60b6962d95952775cac5e90cd", [:rebar3], [], "hexpm"}, } From 64feee7dd4597b15992666226409e9df1406cb09 Mon Sep 17 00:00:00 2001 From: hswick Date: Tue, 9 Oct 2018 17:17:29 -0500 Subject: [PATCH 2/5] Generic client, uses ipc/http based on config --- config/config.exs | 4 +++- lib/exw3.ex | 56 +++++++++++++++++++++++++++++++---------------- 2 files changed, 40 insertions(+), 20 deletions(-) diff --git a/config/config.exs b/config/config.exs index 08b1eb8..2e3339a 100644 --- a/config/config.exs +++ b/config/config.exs @@ -25,4 +25,6 @@ use Mix.Config # # import_config "#{Mix.env}.exs" config :ethereumex, - url: "http://localhost:8545" + url: "http://localhost:8545", + client_type: :ipc, + ipc_path: "/.local/share/io.parity.ethereum/jsonrpc.ipc" diff --git a/lib/exw3.ex b/lib/exw3.ex index 221289d..309c561 100644 --- a/lib/exw3.ex +++ b/lib/exw3.ex @@ -31,6 +31,8 @@ defmodule ExW3 do :tether => 1_000_000_000_000_000_000_000_000_000_000 } + @client_type Application.get_env(:ethereumex, :client_type, :http) + @spec get_unit_map() :: %{} @doc "Returns the map used for ether unit conversion" def get_unit_map do @@ -117,10 +119,18 @@ defmodule ExW3 do to_checksum_address(address) == address end + defp call_client(method_name, arguments \\ []) do + case @client_type do + :http -> apply(Ethereumex.HttpClient, method_name, arguments) + :ipc -> apply(Ethereumex.IpcClient, method_name, arguments) + _ -> {:error, :invalid_client_type} + end + end + @spec accounts() :: list() @doc "returns all available accounts" def accounts do - case Ethereumex.HttpClient.eth_accounts() do + case call_client(:eth_accounts) do {:ok, accounts} -> accounts err -> err end @@ -137,7 +147,7 @@ defmodule ExW3 do @spec block_number() :: integer() @doc "Returns the current block number" def block_number do - case Ethereumex.HttpClient.eth_block_number() do + case call_client(:eth_block_number) do {:ok, block_number} -> block_number |> to_decimal @@ -149,7 +159,7 @@ defmodule ExW3 do @spec balance(binary()) :: integer() @doc "Returns current balance of account" def balance(account) do - case Ethereumex.HttpClient.eth_get_balance(account) do + case call_client(:eth_get_balance, [account]) do {:ok, balance} -> balance |> to_decimal @@ -170,22 +180,22 @@ defmodule ExW3 do @spec tx_receipt(binary()) :: %{} @doc "Returns transaction receipt for specified transaction hash(id)" def tx_receipt(tx_hash) do - case Ethereumex.HttpClient.eth_get_transaction_receipt(tx_hash) do + case call_client(:eth_get_transaction_receipt, [tx_hash]) do {:ok, receipt} -> - Map.merge( + {:ok, Map.merge( receipt, keys_to_decimal(receipt, ["blockNumber", "cumulativeGasUsed", "gasUsed"]) - ) + )} err -> - err + {:error, err} end end @spec block(integer()) :: any() @doc "Returns block data for specified block number" def block(block_number) do - case Ethereumex.HttpClient.eth_get_block_by_number(block_number, true) do + case call_client(:eth_get_block_by_number, [block_number, true]) do {:ok, block} -> block err -> err end @@ -194,7 +204,7 @@ defmodule ExW3 do @spec new_filter(%{}) :: binary() @doc "Creates a new filter, returns filter id. For more sophisticated use, prefer ExW3.Contract.filter." def new_filter(map) do - case Ethereumex.HttpClient.eth_new_filter(map) do + case call_client(:eth_new_filter, [map]) do {:ok, filter_id} -> filter_id err -> err end @@ -203,7 +213,7 @@ defmodule ExW3 do @spec get_filter_changes(binary()) :: any() @doc "Gets event changes (logs) by filter. Unlike ExW3.Contract.get_filter_changes it does not return the data in a formatted way" def get_filter_changes(filter_id) do - case Ethereumex.HttpClient.eth_get_filter_changes(filter_id) do + case call_client(:eth_get_filter_changes, [filter_id]) do {:ok, changes} -> changes err -> err end @@ -212,7 +222,7 @@ defmodule ExW3 do @spec uninstall_filter(binary()) :: boolean() @doc "Uninstalls filter from the ethereum node" def uninstall_filter(filter_id) do - case Ethereumex.HttpClient.eth_uninstall_filter(filter_id) do + case call_client(:eth_uninstall_filter, [filter_id]) do {:ok, result} -> result err -> err end @@ -222,7 +232,7 @@ defmodule ExW3 do @doc "Mines number of blocks specified. Default is 1" def mine(num_blocks \\ 1) do for _ <- 0..(num_blocks - 1) do - Ethereumex.HttpClient.request("evm_mine", [], []) + call_client(:request, ["evm_mine", [], []]) end end @@ -232,6 +242,14 @@ defmodule ExW3 do ExthCrypto.Hash.Keccak.kec(signature) |> Base.encode16(case: :lower) end + def eth_call(arguments) do + call_client(:eth_call, arguments) + end + + def eth_send(arguments) do + call_client(:eth_send_transaction, arguments) + end + @spec decode_event(binary(), binary()) :: any() @doc "Decodes event based on given data and provided signature" def decode_event(data, signature) do @@ -603,19 +621,19 @@ defmodule ExW3 do gas: gas } - {:ok, tx_hash} = Ethereumex.HttpClient.eth_send_transaction(tx) + {:ok, tx_hash} = ExW3.eth_send([tx]) - {:ok, tx_receipt} = Ethereumex.HttpClient.eth_get_transaction_receipt(tx_hash) + {:ok, tx_receipt} = ExW3.tx_receipt(tx_hash) {tx_receipt["contractAddress"], tx_hash} end def eth_call_helper(address, abi, method_name, args) do result = - Ethereumex.HttpClient.eth_call(%{ + ExW3.eth_call([%{ to: address, data: "0x#{ExW3.encode_method_call(abi, method_name, args)}" - }) + }]) case result do {:ok, data} -> ([:ok] ++ ExW3.decode_output(abi, method_name, data)) |> List.to_tuple() @@ -626,14 +644,14 @@ defmodule ExW3 do def eth_send_helper(address, abi, method_name, args, options) do gas = ExW3.encode_option(options[:gas]) - Ethereumex.HttpClient.eth_send_transaction( + ExW3.eth_send([ Map.merge( %{ to: address, data: "0x#{ExW3.encode_method_call(abi, method_name, args)}" }, Map.put(options, :gas, gas) - ) + )] ) end @@ -893,7 +911,7 @@ defmodule ExW3 do def handle_call({:tx_receipt, {contract_name, tx_hash}}, _from, state) do contract_info = state[contract_name] - receipt = ExW3.tx_receipt(tx_hash) + {:ok, receipt} = ExW3.tx_receipt(tx_hash) events = contract_info[:events] logs = receipt["logs"] From 8581ffe0902a1cce0941331c0b3d1879f23dbe83 Mon Sep 17 00:00:00 2001 From: hswick Date: Tue, 9 Oct 2018 17:40:17 -0500 Subject: [PATCH 3/5] Documentation --- README.md | 36 ++++++++++++++++++++++++++---------- lib/exw3.ex | 4 ++++ 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 6d68c4b..3926ec2 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ end ``` ## Overview -ExW3 is a wrapper around ethereumex to provide a high level, user friendly json rpc api. It currently ONLY supports http. The primary feature of this library is a handy abstraction for working with smart contracts. +ExW3 is a wrapper around ethereumex to provide a high level, user friendly json rpc api. This library is focused on providing a handy abstraction for working with smart contracts, and any other relevant utilities. ## Usage @@ -34,15 +34,33 @@ If Parity complains about password or missing account, try parity --chain dev --unlock=0x00a329c0648769a73afac7f9381e08fb43dbea72 ``` -Make sure your config includes: +### Http + +To use Ethereumex's HttpClient simply set your config like this: ```elixir config :ethereumex, + client_type: :http, url: "http://localhost:8545" ``` -Currently, ExW3 supports a handful of json rpc commands. Mostly just the useful ones. If it doesn't support a specific commands you can always use the [Ethereumex](https://github.com/exthereum/ethereumex) commands. +### Ipc + +If you want to use IpcClient set your config to something like this: +```elixir +config :ethereumex, + client_type: :ipc, + ipc_path: "/.local/share/io.parity.ethereum/jsonrpc.ipc" +``` + +Provide an absolute path to the ipc socket provided by whatever Ethereum client you are running. You don't need to include the home directory, as that will be prepended to the path provided. -Check out the [documentation](https://hexdocs.pm/exw3/ExW3.html) +* NOTE * Use of Ipc is recommended, as it is more secure and significantly faster. + +Currently, ExW3 supports a handful of json rpc commands. Primarily the ones that get used the most. If ExW3 doesn't provide a specific command, you can always use the [Ethereumex](https://github.com/exthereum/ethereumex) commands. + +Check out the [documentation](https://hexdocs.pm/exw3/ExW3.html) for more details of the API. + +### Example ```elixir iex(1)> accounts = ExW3.accounts() @@ -89,13 +107,11 @@ iex(11)> ExW3.Contract.call(:SimpleStorage, :get) {:ok, 1} ``` -## Asynchronous +## Address Type -ExW3 provides async versions of `call` and `send`. They both return a `Task` that can be awaited on. - -```elixir -t = ExW3.Contract.call_async(:SimpleStorage, :get) -{:ok, data} = Task.await(t) +If you are familiar with web3.js you may find the way ExW3 handles addresses unintuitive. ExW3's abi encoder interprets the address type as an uint160. If you are using an address as an option to a transaction like `:from` or `:to` this will work as expected. However, if one of your smart contracts is expecting an address type for an input parameter then you will need to do this: +``` +a = ExW3.to_decimal("0x88838e84a401a1d6162290a1a765507c4a83f5e050658a83992a912f42149ca5") ``` ## Events diff --git a/lib/exw3.ex b/lib/exw3.ex index 309c561..b5465d2 100644 --- a/lib/exw3.ex +++ b/lib/exw3.ex @@ -242,10 +242,14 @@ defmodule ExW3 do ExthCrypto.Hash.Keccak.kec(signature) |> Base.encode16(case: :lower) end + @spec eth_call([]) :: any() + @doc "Simple eth_call to client. Recommended to use ExW3.Contract.call instead." def eth_call(arguments) do call_client(:eth_call, arguments) end + @spec eth_send([]) :: any() + @doc "Simple eth_send_transaction. Recommended to use ExW3.Contract.send instead." def eth_send(arguments) do call_client(:eth_send_transaction, arguments) end From 60718230753522d6c6942f476c3e0ade694bd40d Mon Sep 17 00:00:00 2001 From: hswick Date: Tue, 9 Oct 2018 17:42:18 -0500 Subject: [PATCH 4/5] Removed send_async and call_async --- lib/exw3.ex | 116 ++++++++++++++++++++++----------------------- test/exw3_test.exs | 49 ++----------------- 2 files changed, 60 insertions(+), 105 deletions(-) diff --git a/lib/exw3.ex b/lib/exw3.ex index b5465d2..d244a93 100644 --- a/lib/exw3.ex +++ b/lib/exw3.ex @@ -124,8 +124,8 @@ defmodule ExW3 do :http -> apply(Ethereumex.HttpClient, method_name, arguments) :ipc -> apply(Ethereumex.IpcClient, method_name, arguments) _ -> {:error, :invalid_client_type} - end - end + end + end @spec accounts() :: list() @doc "returns all available accounts" @@ -182,10 +182,11 @@ defmodule ExW3 do def tx_receipt(tx_hash) do case call_client(:eth_get_transaction_receipt, [tx_hash]) do {:ok, receipt} -> - {:ok, Map.merge( - receipt, - keys_to_decimal(receipt, ["blockNumber", "cumulativeGasUsed", "gasUsed"]) - )} + {:ok, + Map.merge( + receipt, + keys_to_decimal(receipt, ["blockNumber", "cumulativeGasUsed", "gasUsed"]) + )} err -> {:error, err} @@ -436,7 +437,7 @@ defmodule ExW3 do @doc "Uninstalls the filter, and deletes the data associated with the filter id" def uninstall_filter(filter_id) do GenServer.cast(ContractManager, {:uninstall_filter, filter_id}) - end + end @spec at(keyword(), binary()) :: :ok @doc "Sets the address for the contract specified by the name argument" @@ -462,22 +463,6 @@ defmodule ExW3 do GenServer.call(ContractManager, {:send, {contract_name, method_name, args, options}}) end - @spec call_async(keyword(), keyword(), []) :: {:ok, any()} - @doc "Use a Contract's method with an eth_call. Returns a Task to be awaited." - def call_async(contract_name, method_name, args \\ []) do - Task.async(fn -> - GenServer.call(ContractManager, {:call, {contract_name, method_name, args}}) - end) - end - - @spec send_async(keyword(), keyword(), [], %{}) :: {:ok, binary()} - @doc "Use a Contract's method with an eth_sendTransaction. Returns a Task to be awaited." - def send_async(contract_name, method_name, args, options) do - Task.async(fn -> - GenServer.call(ContractManager, {:send, {contract_name, method_name, args, options}}) - end) - end - @spec tx_receipt(keyword(), binary()) :: %{} @doc "Returns a formatted transaction receipt for the given transaction hash(id)" def tx_receipt(contract_name, tx_hash) do @@ -497,11 +482,11 @@ defmodule ExW3 do @doc "Using saved information related to the filter id, event logs are formatted properly" def get_filter_changes(filter_id) do GenServer.call( - ContractManager, - {:get_filter_changes, filter_id} + ContractManager, + {:get_filter_changes, filter_id} ) end - + # Server def init(state) do @@ -579,8 +564,8 @@ defmodule ExW3 do end) [ - events: Enum.into(signature_types_map, %{}), - event_names: Enum.into(names_map, %{}) + events: Enum.into(signature_types_map, %{}), + event_names: Enum.into(names_map, %{}) ] end @@ -634,10 +619,12 @@ defmodule ExW3 do def eth_call_helper(address, abi, method_name, args) do result = - ExW3.eth_call([%{ - to: address, - data: "0x#{ExW3.encode_method_call(abi, method_name, args)}" - }]) + ExW3.eth_call([ + %{ + to: address, + data: "0x#{ExW3.encode_method_call(abi, method_name, args)}" + } + ]) case result do {:ok, data} -> ([:ok] ++ ExW3.decode_output(abi, method_name, data)) |> List.to_tuple() @@ -655,13 +642,13 @@ defmodule ExW3 do data: "0x#{ExW3.encode_method_call(abi, method_name, args)}" }, Map.put(options, :gas, gas) - )] - ) + ) + ]) end defp register_helper(contract_info) do if contract_info[:abi] do - contract_info ++ init_events(contract_info[:abi]) + contract_info ++ init_events(contract_info[:abi]) else raise "ABI not provided upon initialization" end @@ -807,7 +794,7 @@ defmodule ExW3 do new_data = Map.merge(indexed_fields, non_indexed_fields) Map.put(log, "data", new_data) - end + end def handle_call({:filter, {contract_name, event_name, event_data}}, _from, state) do contract_info = state[contract_name] @@ -826,38 +813,47 @@ defmodule ExW3 do filter_id = ExW3.new_filter(payload) - {:reply, {:ok, filter_id}, Map.put(state, :filters, Map.put(state[:filters], filter_id, %{contract_name: contract_name, event_name: event_name}))} + {:reply, {:ok, filter_id}, + Map.put( + state, + :filters, + Map.put(state[:filters], filter_id, %{ + contract_name: contract_name, + event_name: event_name + }) + )} end def handle_call({:get_filter_changes, filter_id}, _from, state) do - filter_info = Map.get(state[:filters], filter_id) - event_attributes = get_event_attributes(state, filter_info[:contract_name], filter_info[:event_name]) + + event_attributes = + get_event_attributes(state, filter_info[:contract_name], filter_info[:event_name]) logs = ExW3.get_filter_changes(filter_id) formatted_logs = - if logs != [] do - Enum.map(logs, fn log -> - formatted_log = - Enum.reduce( - [ - ExW3.keys_to_decimal(log, [ - "blockNumber", - "logIndex", - "transactionIndex", - "transactionLogIndex" - ]), - format_log_data(log, event_attributes) - ], - &Map.merge/2 - ) - - formatted_log - end) - else - logs - end + if logs != [] do + Enum.map(logs, fn log -> + formatted_log = + Enum.reduce( + [ + ExW3.keys_to_decimal(log, [ + "blockNumber", + "logIndex", + "transactionIndex", + "transactionLogIndex" + ]), + format_log_data(log, event_attributes) + ], + &Map.merge/2 + ) + + formatted_log + end) + else + logs + end {:reply, {:ok, formatted_logs}, state} end diff --git a/test/exw3_test.exs b/test/exw3_test.exs index 0a1c519..ca397d2 100644 --- a/test/exw3_test.exs +++ b/test/exw3_test.exs @@ -186,9 +186,8 @@ defmodule EXW3Test do end test "Testing formatted get filter changes", context do - ExW3.Contract.register(:EventTester, abi: context[:event_tester_abi]) - + {:ok, address, _} = ExW3.Contract.deploy( :EventTester, @@ -240,7 +239,7 @@ defmodule EXW3Test do {:ok, change_logs} = ExW3.Contract.get_filter_changes(indexed_filter_id) event_log = Enum.at(change_logs, 0) - + assert event_log |> is_map log_data = Map.get(event_log, "data") assert log_data |> is_map @@ -279,7 +278,7 @@ defmodule EXW3Test do assert Map.get(log_data, "num") == 46 assert ExW3.bytes_to_string(Map.get(log_data, "data")) == "Hello, World!" assert Map.get(log_data, "otherNum") == 42 - + ExW3.Contract.uninstall_filter(indexed_filter_id) # Tests filter with map params @@ -311,9 +310,8 @@ defmodule EXW3Test do assert Map.get(log_data, "num") == 46 assert ExW3.bytes_to_string(Map.get(log_data, "data")) == "Hello, World!" assert Map.get(log_data, "otherNum") == 42 - + ExW3.Contract.uninstall_filter(indexed_filter_id) - end test "starts a Contract GenServer for Complex contract", context do @@ -528,43 +526,4 @@ defmodule EXW3Test do assert ExW3.from_wei(1_000_000_000_000_000_000, :gether) == 0.000000001 assert ExW3.from_wei(1_000_000_000_000_000_000, :tether) == 0.000000000001 end - - test "send and call sync with SimpleStorage", context do - ExW3.Contract.register(:SimpleStorage, abi: context[:simple_storage_abi]) - - {:ok, address, _} = - ExW3.Contract.deploy( - :SimpleStorage, - bin: ExW3.load_bin("test/examples/build/SimpleStorage.bin"), - args: [], - options: %{ - gas: 300_000, - from: Enum.at(context[:accounts], 0) - } - ) - - ExW3.Contract.at(:SimpleStorage, address) - - assert address == ExW3.Contract.address(:SimpleStorage) - - t = ExW3.Contract.call_async(:SimpleStorage, :get) - - {:ok, data} = Task.await(t) - - assert data == 0 - - t = - ExW3.Contract.send_async(:SimpleStorage, :set, [1], %{ - from: Enum.at(context[:accounts], 0), - gas: 50_000 - }) - - Task.await(t) - - t = ExW3.Contract.call_async(:SimpleStorage, :get) - - {:ok, data} = Task.await(t) - - assert data == 1 - end end From 1be6299c581943005fbb01bbe56da1b908d13898 Mon Sep 17 00:00:00 2001 From: hswick Date: Tue, 9 Oct 2018 17:42:57 -0500 Subject: [PATCH 5/5] Bumped version number --- mix.exs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mix.exs b/mix.exs index 0d28992..6e5cf19 100644 --- a/mix.exs +++ b/mix.exs @@ -4,7 +4,7 @@ defmodule ExW3.MixProject do def project do [ app: :exw3, - version: "0.3.0", + version: "0.4.0", elixir: "~> 1.7.2", build_embedded: Mix.env == :prod, start_permanent: Mix.env == :prod,