Add error treatment to the 'ex_abi' lib

pull/279/head
Amanda Sposito 6 years ago
parent f772e1a56f
commit e545841407
  1. 43
      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
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" => [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()
def query_contract(address_hash, functions) do
@ -33,13 +47,26 @@ defmodule Explorer.SmartContract.Reader do
|> Chain.address_hash_to_smart_contract()
|> Map.get(:abi)
blockchain_result =
abi
|> Encoder.encode_abi(functions)
|> Enum.map(&setup_call_payload(&1, contract_address))
|> EthereumJSONRPC.execute_contract_functions()
try do
blockchain_result =
abi
|> Encoder.encode_abi(functions)
|> Enum.map(&setup_call_payload(&1, contract_address))
|> EthereumJSONRPC.execute_contract_functions()
Encoder.decode_abi_results(blockchain_result, abi, functions)
rescue
error ->
format_error(functions, error.message)
end
end
Encoder.decode_abi_results(blockchain_result, abi, functions)
defp format_error(functions, message) do
functions
|> Enum.map(fn {function_name, _args} ->
%{function_name => [message]}
end)
|> List.first()
end
@doc """

@ -1,5 +1,5 @@
defmodule Explorer.SmartContract.ReaderTest do
use ExUnit.Case, async: true
use ExUnit.Case
use Explorer.DataCase
doctest Explorer.SmartContract.Reader
@ -39,6 +39,34 @@ defmodule Explorer.SmartContract.ReaderTest do
assert Reader.query_contract(hash, %{"get" => []}) == %{"get" => [0]}
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
describe "setup_call_payload/2" do

Loading…
Cancel
Save