From 1917e96ec6dd9d3fe5671d5f6a8cd7b83fdc6823 Mon Sep 17 00:00:00 2001 From: nikitosing Date: Thu, 24 Feb 2022 23:44:02 +0300 Subject: [PATCH] Add functions overloading support --- .dialyzer-ignore | 2 +- CHANGELOG.md | 1 + .../controllers/smart_contract_controller.ex | 4 +--- .../smart_contract/_functions.html.eex | 13 ++++++++++++- apps/block_scout_web/priv/gettext/default.pot | 10 +++++----- .../priv/gettext/en/LC_MESSAGES/default.po | 10 +++++----- .../lib/explorer/smart_contract/reader.ex | 17 +++++++++-------- 7 files changed, 34 insertions(+), 23 deletions(-) diff --git a/.dialyzer-ignore b/.dialyzer-ignore index 7f7f8757a4..d45a57f55c 100644 --- a/.dialyzer-ignore +++ b/.dialyzer-ignore @@ -18,7 +18,7 @@ lib/phoenix/router.ex:402 lib/block_scout_web/views/layout_view.ex:145: The call 'Elixir.Poison.Parser':'parse!' lib/block_scout_web/views/layout_view.ex:237: The call 'Elixir.Poison.Parser':'parse!' lib/block_scout_web/controllers/api/rpc/transaction_controller.ex:22 -lib/explorer/smart_contract/reader.ex:436 +lib/explorer/smart_contract/reader.ex:435 lib/indexer/fetcher/token_total_supply_on_demand.ex:16 lib/explorer/exchange_rates/source.ex:110 lib/explorer/exchange_rates/source.ex:113 diff --git a/CHANGELOG.md b/CHANGELOG.md index 02b8f97705..025f8f8849 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ ## Current ### Features +- [#5232](https://github.com/blockscout/blockscout/pull/5232) - Contract Read Page: Add functions overloading support - [#5220](https://github.com/blockscout/blockscout/pull/5220) - Add info about proxy contracts to api methods response - [#5200](https://github.com/blockscout/blockscout/pull/5200) - Docker-compose configuration - [#5105](https://github.com/blockscout/blockscout/pull/5105) - Redesign token page diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/smart_contract_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/smart_contract_controller.ex index 6c3fb9843e..621dd661cd 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/smart_contract_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/smart_contract_controller.ex @@ -114,15 +114,13 @@ defmodule BlockScoutWeb.SmartContractController do address_hash, %{method_id: params["method_id"], args: args}, contract_type, - params["function_name"], params["from"] ) else Reader.query_function_with_names( address_hash, %{method_id: params["method_id"], args: args}, - contract_type, - params["function_name"] + contract_type ) end diff --git a/apps/block_scout_web/lib/block_scout_web/templates/smart_contract/_functions.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/smart_contract/_functions.html.eex index 24ded23fc1..191c9836e0 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/smart_contract/_functions.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/smart_contract/_functions.html.eex @@ -55,7 +55,18 @@ end %> <%= render BlockScoutWeb.SmartContractView, "_pending_contract_write.html" %> -
" data-type="<%= @contract_type %>" data-url="<%= smart_contract_path(@conn, :show, Address.checksum(@address.hash)) %>" data-contract-address="<%= @address.hash %>" data-contract-abi="<%= @contract_abi %>" data-implementation-abi="<%= @implementation_abi %>" data-chain-id="<%= Explorer.Chain.Cache.NetVersion.get_version() %>"> + <% function_abi = + case Jason.encode([function]) do + {:ok, abi_string} -> + abi_string + _ -> + if @contract_type == "proxy" do + @implementation_abi + else + @contract_abi + end + end %> + " data-type="<%= @contract_type %>" data-url="<%= smart_contract_path(@conn, :show, Address.checksum(@address.hash)) %>" data-contract-address="<%= @address.hash %>" data-contract-abi="<%= function_abi %>" data-implementation-abi="<%= function_abi %>" data-chain-id="<%= Explorer.Chain.Cache.NetVersion.get_version() %>"> diff --git a/apps/block_scout_web/priv/gettext/default.pot b/apps/block_scout_web/priv/gettext/default.pot index 627c538bfe..0eb7d65dc1 100644 --- a/apps/block_scout_web/priv/gettext/default.pot +++ b/apps/block_scout_web/priv/gettext/default.pot @@ -1028,8 +1028,8 @@ msgstr "" #, elixir-format #: lib/block_scout_web/templates/address_token/overview.html.eex:1 -#: lib/block_scout_web/templates/smart_contract/_functions.html.eex:93 lib/block_scout_web/templates/smart_contract/_functions.html.eex:93 -#: lib/block_scout_web/templates/smart_contract/_functions.html.eex:135 +#: lib/block_scout_web/templates/smart_contract/_functions.html.eex:104 lib/block_scout_web/templates/smart_contract/_functions.html.eex:104 +#: lib/block_scout_web/templates/smart_contract/_functions.html.eex:146 msgid "ETH" msgstr "" @@ -1926,7 +1926,7 @@ msgid "QR Code" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/smart_contract/_functions.html.eex:98 +#: lib/block_scout_web/templates/smart_contract/_functions.html.eex:109 msgid "Query" msgstr "" @@ -3093,7 +3093,7 @@ msgid "Vyper contract" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/smart_contract/_functions.html.eex:134 +#: lib/block_scout_web/templates/smart_contract/_functions.html.eex:145 msgid "WEI" msgstr "" @@ -3148,7 +3148,7 @@ msgid "Working Stake Amount" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/smart_contract/_functions.html.eex:98 +#: lib/block_scout_web/templates/smart_contract/_functions.html.eex:109 msgid "Write" msgstr "" diff --git a/apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po b/apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po index 627c538bfe..0eb7d65dc1 100644 --- a/apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po +++ b/apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po @@ -1028,8 +1028,8 @@ msgstr "" #, elixir-format #: lib/block_scout_web/templates/address_token/overview.html.eex:1 -#: lib/block_scout_web/templates/smart_contract/_functions.html.eex:93 lib/block_scout_web/templates/smart_contract/_functions.html.eex:93 -#: lib/block_scout_web/templates/smart_contract/_functions.html.eex:135 +#: lib/block_scout_web/templates/smart_contract/_functions.html.eex:104 lib/block_scout_web/templates/smart_contract/_functions.html.eex:104 +#: lib/block_scout_web/templates/smart_contract/_functions.html.eex:146 msgid "ETH" msgstr "" @@ -1926,7 +1926,7 @@ msgid "QR Code" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/smart_contract/_functions.html.eex:98 +#: lib/block_scout_web/templates/smart_contract/_functions.html.eex:109 msgid "Query" msgstr "" @@ -3093,7 +3093,7 @@ msgid "Vyper contract" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/smart_contract/_functions.html.eex:134 +#: lib/block_scout_web/templates/smart_contract/_functions.html.eex:145 msgid "WEI" msgstr "" @@ -3148,7 +3148,7 @@ msgid "Working Stake Amount" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/smart_contract/_functions.html.eex:98 +#: lib/block_scout_web/templates/smart_contract/_functions.html.eex:109 msgid "Write" msgstr "" diff --git a/apps/explorer/lib/explorer/smart_contract/reader.ex b/apps/explorer/lib/explorer/smart_contract/reader.ex index 16e03cd48b..89d5a7d40a 100644 --- a/apps/explorer/lib/explorer/smart_contract/reader.ex +++ b/apps/explorer/lib/explorer/smart_contract/reader.ex @@ -367,13 +367,13 @@ defmodule Explorer.SmartContract.Reader do `type` could be :proxy or :reqular if ethereumJSONRPC will return some errors it will represented as map """ - @spec query_function_with_names(Hash.t(), %{method_id: String.t(), args: [term()] | nil}, atom(), String.t()) :: %{ + @spec query_function_with_names(Hash.t(), %{method_id: String.t(), args: [term()] | nil}, atom()) :: %{ :names => [any()], :output => [%{}] } - def query_function_with_names(contract_address_hash, %{method_id: method_id, args: args}, type, function_name) do + def query_function_with_names(contract_address_hash, %{method_id: method_id, args: args}, type) do outputs = query_function(contract_address_hash, %{method_id: method_id, args: args}, type, true) - names = parse_names_from_abi(get_abi(contract_address_hash, type), function_name) + names = parse_names_from_abi(get_abi(contract_address_hash, type), method_id) %{output: outputs, names: names} end @@ -386,12 +386,11 @@ defmodule Explorer.SmartContract.Reader do Hash.t(), %{method_id: String.t(), args: [term()] | nil}, atom(), - String.t(), String.t() ) :: %{:names => [any()], :output => [%{}]} - def query_function_with_names(contract_address_hash, %{method_id: method_id, args: args}, type, function_name, from) do + def query_function_with_names(contract_address_hash, %{method_id: method_id, args: args}, type, from) do outputs = query_function(contract_address_hash, %{method_id: method_id, args: args}, type, from, true) - names = parse_names_from_abi(get_abi(contract_address_hash, type), function_name) + names = parse_names_from_abi(get_abi(contract_address_hash, type), method_id) %{output: outputs, names: names} end @@ -462,8 +461,10 @@ defmodule Explorer.SmartContract.Reader do end end - defp parse_names_from_abi(abi, function_name) do - function = Enum.find(abi, fn el -> el["type"] == "function" and el["name"] == function_name end) + defp parse_names_from_abi(abi, method_id) do + function = + Enum.find(get_abi_with_method_id(abi), fn el -> el["type"] == "function" and el["method_id"] == method_id end) + outputs_to_list(function["outputs"]) end