Add error treatment to the 'ex_abi' lib

pull/279/head
Amanda Sposito 6 years ago
parent f772e1a56f
commit e545841407
  1. 31
      apps/explorer/lib/explorer/smart_contract/reader.ex
  2. 30
      apps/explorer/test/explorer/smart_contract/reader_test.exs

@ -18,11 +18,25 @@ defmodule Explorer.SmartContract.Reader do
Note that for this example to work the database must be up to date with the Note that for this example to work the database must be up to date with the
information available in the blockchain. information available in the blockchain.
Explorer.SmartContract.Reader.query_contract( ```
"0x7e50612682b8ee2a8bb94774d50d6c2955726526", $ Explorer.SmartContract.Reader.query_contract(
%Explorer.Chain.Hash{
byte_count: 20,
bytes: <<0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0>>
},
%{"sum" => [20, 22]} %{"sum" => [20, 22]}
) )
# => %{"sum" => [42]} # => %{"sum" => [42]}
$ Explorer.SmartContract.Reader.query_contract(
%Explorer.Chain.Hash{
byte_count: 20,
bytes: <<0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0>>
},
%{"sum" => [1, "abc"]}
)
# => %{"sum" => ["Data overflow encoding int, data `abc` cannot fit in 256 bits"]}
```
""" """
@spec query_contract(%Explorer.Chain.Hash{}, %{String.t() => [term()]}) :: map() @spec query_contract(%Explorer.Chain.Hash{}, %{String.t() => [term()]}) :: map()
def query_contract(address_hash, functions) do def query_contract(address_hash, functions) do
@ -33,6 +47,7 @@ defmodule Explorer.SmartContract.Reader do
|> Chain.address_hash_to_smart_contract() |> Chain.address_hash_to_smart_contract()
|> Map.get(:abi) |> Map.get(:abi)
try do
blockchain_result = blockchain_result =
abi abi
|> Encoder.encode_abi(functions) |> Encoder.encode_abi(functions)
@ -40,6 +55,18 @@ defmodule Explorer.SmartContract.Reader do
|> EthereumJSONRPC.execute_contract_functions() |> EthereumJSONRPC.execute_contract_functions()
Encoder.decode_abi_results(blockchain_result, abi, functions) Encoder.decode_abi_results(blockchain_result, abi, functions)
rescue
error ->
format_error(functions, error.message)
end
end
defp format_error(functions, message) do
functions
|> Enum.map(fn {function_name, _args} ->
%{function_name => [message]}
end)
|> List.first()
end end
@doc """ @doc """

@ -1,5 +1,5 @@
defmodule Explorer.SmartContract.ReaderTest do defmodule Explorer.SmartContract.ReaderTest do
use ExUnit.Case, async: true use ExUnit.Case
use Explorer.DataCase use Explorer.DataCase
doctest Explorer.SmartContract.Reader doctest Explorer.SmartContract.Reader
@ -39,6 +39,34 @@ defmodule Explorer.SmartContract.ReaderTest do
assert Reader.query_contract(hash, %{"get" => []}) == %{"get" => [0]} assert Reader.query_contract(hash, %{"get" => []}) == %{"get" => [0]}
end end
test "won't raise error when there is a problem with the params to consult the blockchain" do
smart_contract =
insert(
:smart_contract,
abi: [
%{
"constant" => true,
"inputs" => [
%{"name" => "a", "type" => "int256"},
%{"name" => "b", "type" => "int256"},
%{"name" => "c", "type" => "int256"},
%{"name" => "d", "type" => "int256"}
],
"name" => "sum",
"outputs" => [%{"name" => "", "type" => "int256"}],
"payable" => false,
"stateMutability" => "pure",
"type" => "function"
}
]
)
wrong_args = %{"sum" => [1, 1, 1, "abc"]}
assert %{"sum" => ["Data overflow encoding int, data `abc` cannot fit in 256 bits"]} =
Reader.query_contract(smart_contract.address_hash, wrong_args)
end
end end
describe "setup_call_payload/2" do describe "setup_call_payload/2" do

Loading…
Cancel
Save