diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6717a43f1f..1ad5058c8a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,7 @@
## Current
### Features
+- [#2555](https://github.com/poanetwork/blockscout/pull/2555) - find and show decoding candidates for logs
- [#2596](https://github.com/poanetwork/blockscout/pull/2596) - support AuRa's empty step reward type
- [#2561](https://github.com/poanetwork/blockscout/pull/2561) - Add token's type to the response of tokenlist method
- [#2499](https://github.com/poanetwork/blockscout/pull/2499) - import emission reward ranges
diff --git a/apps/block_scout_web/lib/block_scout_web/templates/address_logs/_logs.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/address_logs/_logs.html.eex
index e49adf8801..92a8ebc6cc 100644
--- a/apps/block_scout_web/lib/block_scout_web/templates/address_logs/_logs.html.eex
+++ b/apps/block_scout_web/lib/block_scout_web/templates/address_logs/_logs.html.eex
@@ -1,4 +1,19 @@
">
+ <% decoded_result = decode(@log, @log.transaction) %>
+ <%= case decoded_result do %>
+ <%= {:error, :contract_not_verified, _cadidates} -> %>
+
+ <%= gettext "To see accurate decoded input data, the contract must be verified." %>
+ <%= case @log.transaction do %>
+ <% %{to_address: %{hash: hash}} -> %>
+ <%= gettext "Verify the contract " %>
<%= gettext "here" %>
+ <% _ -> %>
+ <%= nil %>
+ <% end %>
+
+ <% _ -> %>
+ <%= nil %>
+ <% end %>
- <%= gettext "Transaction" %>
-
@@ -11,19 +26,7 @@
) %>
- <%= case decode(@log, @log.transaction) do %>
- <% {:error, :contract_not_verified} -> %>
- - <%= gettext "Decoded" %>
- -
-
- <%= gettext "To see decoded input data, the contract must be verified." %>
- <%= case @log.transaction do %>
- <% %{to_address: %{hash: hash}} -> %>
- <%= gettext "Verify the contract " %>
<%= gettext "here" %>
- <% _ -> %>
- <%= nil %>
- <% end %>
-
+ <%= case decoded_result do %>
<% {:error, :could_not_decode} -> %>
- <%= gettext "Decoded" %>
-
@@ -81,7 +84,61 @@
<% end %>
-
+
+ <% {:error, :contract_not_verified, results} -> %>
+ <%= for {:ok, method_id, text, mapping} <- results do %>
+ <%= gettext "Decoded" %>
+
+
+
+
" class="table thead-light table-bordered">
+
+ |
+ <%= gettext "Name" %> |
+ <%= gettext "Type" %> |
+ <%= gettext "Indexed?" %> |
+ <%= gettext "Data" %> |
+
+ <%= for {name, type, indexed?, value} <- mapping do %>
+
+
+ <%= case BlockScoutWeb.ABIEncodedValueView.copy_text(type, value) do %>
+ <% :error -> %>
+ <%= nil %>
+ <% copy_text -> %>
+
+
+
+ <% end %>
+ |
+ <%= name %> |
+ <%= type %> |
+ <%= indexed? %> |
+
+ <%= BlockScoutWeb.ABIEncodedValueView.value_html(type, value) %>
+ |
+
+ <% end %>
+
+
+ <% end %>
<% _ -> %>
<%= nil %>
<% end %>
diff --git a/apps/block_scout_web/lib/block_scout_web/templates/transaction_log/_logs.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/transaction_log/_logs.html.eex
index c63502669b..49a18bf84d 100644
--- a/apps/block_scout_web/lib/block_scout_web/templates/transaction_log/_logs.html.eex
+++ b/apps/block_scout_web/lib/block_scout_web/templates/transaction_log/_logs.html.eex
@@ -1,4 +1,20 @@
+ <% decoded_result = decode(@log, @transaction) %>
+ <%= case decoded_result do %>
+ <%= {:error, :contract_not_verified, _cadidates} -> %>
+
+ <%= gettext "To see accurate decoded input data, the contract must be verified." %>
+ <%= case @transaction do %>
+ <% %{to_address: %{hash: hash}} -> %>
+ <%= gettext "Verify the contract " %>
<%= gettext "here" %>
+ <% _ -> %>
+ <%= nil %>
+ <% end %>
+
+ <% _ -> %>
+ <%= nil %>
+ <% end %>
+
- <%= gettext "Address" %>
-
@@ -11,19 +27,7 @@
) %>
- <%= case decode(@log, @transaction) do %>
- <% {:error, :contract_not_verified} -> %>
- - <%= gettext "Decoded" %>
- -
-
- <%= gettext "To see decoded input data, the contract must be verified." %>
- <%= case @transaction do %>
- <% %{to_address: %{hash: hash}} -> %>
- <%= gettext "Verify the contract " %>
<%= gettext "here" %>
- <% _ -> %>
- <%= nil %>
- <% end %>
-
+ <%= case decoded_result do %>
<% {:error, :could_not_decode} -> %>
- <%= gettext "Decoded" %>
-
@@ -83,7 +87,61 @@
<% end %>
-
+
+ <% {:error, :contract_not_verified, results} -> %>
+ <%= for {:ok, method_id, text, mapping} <- results do %>
+ <%= gettext "Decoded" %>
+
+
+
+
" class="table thead-light table-bordered">
+
+ |
+ <%= gettext "Name" %> |
+ <%= gettext "Type" %> |
+ <%= gettext "Indexed?" %> |
+ <%= gettext "Data" %> |
+
+ <%= for {name, type, indexed?, value} <- mapping do %>
+
+
+ <%= case BlockScoutWeb.ABIEncodedValueView.copy_text(type, value) do %>
+ <% :error -> %>
+ <%= nil %>
+ <% copy_text -> %>
+
+
+
+ <% end %>
+ |
+ <%= name %> |
+ <%= type %> |
+ <%= indexed? %> |
+
+ <%= BlockScoutWeb.ABIEncodedValueView.value_html(type, value) %>
+ |
+
+ <% end %>
+
+
+ <% end %>
<% _ -> %>
<%= nil %>
<% end %>
diff --git a/apps/block_scout_web/priv/gettext/default.pot b/apps/block_scout_web/priv/gettext/default.pot
index 886a88e4c0..607d83da8a 100644
--- a/apps/block_scout_web/priv/gettext/default.pot
+++ b/apps/block_scout_web/priv/gettext/default.pot
@@ -98,7 +98,7 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_validator_metadata_modal.html.eex:16
-#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:3
+#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:19
#: lib/block_scout_web/views/address_view.ex:99
msgid "Address"
msgstr ""
@@ -558,11 +558,13 @@ msgid "Must be set to:"
msgstr ""
#, elixir-format
-#: lib/block_scout_web/templates/address_logs/_logs.html.eex:50
+#: lib/block_scout_web/templates/address_logs/_logs.html.eex:53
+#: lib/block_scout_web/templates/address_logs/_logs.html.eex:106
#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:52
#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:59
#: lib/block_scout_web/templates/transaction/_decoded_input_body.html.eex:19
-#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:52
+#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:56
+#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:109
msgid "Name"
msgstr ""
@@ -851,7 +853,7 @@ msgid "Total transactions"
msgstr ""
#, elixir-format
-#: lib/block_scout_web/templates/address_logs/_logs.html.eex:3
+#: lib/block_scout_web/templates/address_logs/_logs.html.eex:18
#: lib/block_scout_web/views/transaction_view.ex:262
msgid "Transaction"
msgstr ""
@@ -1128,12 +1130,12 @@ msgid "Static Call"
msgstr ""
#, elixir-format
-#: lib/block_scout_web/templates/address_logs/_logs.html.eex:16
-#: lib/block_scout_web/templates/address_logs/_logs.html.eex:28
-#: lib/block_scout_web/templates/address_logs/_logs.html.eex:34
-#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:16
-#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:28
-#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:36
+#: lib/block_scout_web/templates/address_logs/_logs.html.eex:31
+#: lib/block_scout_web/templates/address_logs/_logs.html.eex:37
+#: lib/block_scout_web/templates/address_logs/_logs.html.eex:90
+#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:32
+#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:40
+#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:93
msgid "Decoded"
msgstr ""
@@ -1142,12 +1144,6 @@ msgstr ""
msgid "Method Id"
msgstr ""
-#, elixir-format
-#: lib/block_scout_web/templates/address_logs/_logs.html.eex:19
-#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:19
-msgid "To see decoded input data, the contract must be verified."
-msgstr ""
-
#, elixir-format
#: lib/block_scout_web/templates/transaction/_decoded_input_body.html.eex:2
#: lib/block_scout_web/templates/transaction/_decoded_input_body.html.eex:16
@@ -1155,16 +1151,16 @@ msgid "Transaction Inputs"
msgstr ""
#, elixir-format
-#: lib/block_scout_web/templates/address_logs/_logs.html.eex:22
+#: lib/block_scout_web/templates/address_logs/_logs.html.eex:9
#: lib/block_scout_web/templates/transaction/_decoded_input.html.eex:11
-#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:22
+#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:9
msgid "Verify the contract "
msgstr ""
#, elixir-format
-#: lib/block_scout_web/templates/address_logs/_logs.html.eex:22
+#: lib/block_scout_web/templates/address_logs/_logs.html.eex:9
#: lib/block_scout_web/templates/transaction/_decoded_input.html.eex:11
-#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:22
+#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:9
msgid "here"
msgstr ""
@@ -1318,7 +1314,9 @@ msgid "To have guaranteed accuracy, use the link above to verify the contract's
msgstr ""
#, elixir-format
+#: lib/block_scout_web/templates/address_logs/_logs.html.eex:6
#: lib/block_scout_web/templates/transaction/_decoded_input.html.eex:8
+#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:6
msgid "To see accurate decoded input data, the contract must be verified."
msgstr ""
@@ -1777,9 +1775,11 @@ msgid "Constructor Arguments"
msgstr ""
#, elixir-format
-#: lib/block_scout_web/templates/address_logs/_logs.html.eex:63
+#: lib/block_scout_web/templates/address_logs/_logs.html.eex:66
+#: lib/block_scout_web/templates/address_logs/_logs.html.eex:119
#: lib/block_scout_web/templates/transaction/_decoded_input_body.html.eex:31
-#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:65
+#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:69
+#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:122
msgid "Copy Value"
msgstr ""
@@ -1789,29 +1789,35 @@ msgid "Create2"
msgstr ""
#, elixir-format
-#: lib/block_scout_web/templates/address_logs/_logs.html.eex:53
-#: lib/block_scout_web/templates/address_logs/_logs.html.eex:118
+#: lib/block_scout_web/templates/address_logs/_logs.html.eex:56
+#: lib/block_scout_web/templates/address_logs/_logs.html.eex:109
+#: lib/block_scout_web/templates/address_logs/_logs.html.eex:175
#: lib/block_scout_web/templates/transaction/_decoded_input_body.html.eex:21
-#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:55
-#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:121
+#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:59
+#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:112
+#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:179
msgid "Data"
msgstr ""
#, elixir-format
-#: lib/block_scout_web/templates/address_logs/_logs.html.eex:31
-#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:31
+#: lib/block_scout_web/templates/address_logs/_logs.html.eex:34
+#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:35
msgid "Failed to decode log data."
msgstr ""
#, elixir-format
-#: lib/block_scout_web/templates/address_logs/_logs.html.eex:52
-#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:54
+#: lib/block_scout_web/templates/address_logs/_logs.html.eex:55
+#: lib/block_scout_web/templates/address_logs/_logs.html.eex:108
+#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:58
+#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:111
msgid "Indexed?"
msgstr ""
#, elixir-format
-#: lib/block_scout_web/templates/address_logs/_logs.html.eex:47
-#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:49
+#: lib/block_scout_web/templates/address_logs/_logs.html.eex:50
+#: lib/block_scout_web/templates/address_logs/_logs.html.eex:103
+#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:53
+#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:106
msgid "Log Data"
msgstr ""
@@ -1823,14 +1829,16 @@ msgid "Reward"
msgstr ""
#, elixir-format
-#: lib/block_scout_web/templates/address_logs/_logs.html.eex:88
-#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:91
+#: lib/block_scout_web/templates/address_logs/_logs.html.eex:145
+#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:149
msgid "Topics"
msgstr ""
#, elixir-format
-#: lib/block_scout_web/templates/address_logs/_logs.html.eex:51
+#: lib/block_scout_web/templates/address_logs/_logs.html.eex:54
+#: lib/block_scout_web/templates/address_logs/_logs.html.eex:107
#: lib/block_scout_web/templates/transaction/_decoded_input_body.html.eex:20
-#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:53
+#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:57
+#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:110
msgid "Type"
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 8fd1e1ff2e..a4ae226813 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
@@ -98,7 +98,7 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_validator_metadata_modal.html.eex:16
-#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:3
+#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:19
#: lib/block_scout_web/views/address_view.ex:99
msgid "Address"
msgstr ""
@@ -558,11 +558,13 @@ msgid "Must be set to:"
msgstr ""
#, elixir-format
-#: lib/block_scout_web/templates/address_logs/_logs.html.eex:50
+#: lib/block_scout_web/templates/address_logs/_logs.html.eex:53
+#: lib/block_scout_web/templates/address_logs/_logs.html.eex:106
#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:52
#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:59
#: lib/block_scout_web/templates/transaction/_decoded_input_body.html.eex:19
-#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:52
+#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:56
+#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:109
msgid "Name"
msgstr ""
@@ -851,7 +853,7 @@ msgid "Total transactions"
msgstr ""
#, elixir-format
-#: lib/block_scout_web/templates/address_logs/_logs.html.eex:3
+#: lib/block_scout_web/templates/address_logs/_logs.html.eex:18
#: lib/block_scout_web/views/transaction_view.ex:262
msgid "Transaction"
msgstr ""
@@ -1128,12 +1130,12 @@ msgid "Static Call"
msgstr ""
#, elixir-format
-#: lib/block_scout_web/templates/address_logs/_logs.html.eex:16
-#: lib/block_scout_web/templates/address_logs/_logs.html.eex:28
-#: lib/block_scout_web/templates/address_logs/_logs.html.eex:34
-#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:16
-#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:28
-#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:36
+#: lib/block_scout_web/templates/address_logs/_logs.html.eex:31
+#: lib/block_scout_web/templates/address_logs/_logs.html.eex:37
+#: lib/block_scout_web/templates/address_logs/_logs.html.eex:90
+#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:32
+#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:40
+#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:93
msgid "Decoded"
msgstr ""
@@ -1142,12 +1144,6 @@ msgstr ""
msgid "Method Id"
msgstr ""
-#, elixir-format
-#: lib/block_scout_web/templates/address_logs/_logs.html.eex:19
-#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:19
-msgid "To see decoded input data, the contract must be verified."
-msgstr ""
-
#, elixir-format
#: lib/block_scout_web/templates/transaction/_decoded_input_body.html.eex:2
#: lib/block_scout_web/templates/transaction/_decoded_input_body.html.eex:16
@@ -1155,16 +1151,16 @@ msgid "Transaction Inputs"
msgstr ""
#, elixir-format
-#: lib/block_scout_web/templates/address_logs/_logs.html.eex:22
+#: lib/block_scout_web/templates/address_logs/_logs.html.eex:9
#: lib/block_scout_web/templates/transaction/_decoded_input.html.eex:11
-#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:22
+#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:9
msgid "Verify the contract "
msgstr ""
#, elixir-format
-#: lib/block_scout_web/templates/address_logs/_logs.html.eex:22
+#: lib/block_scout_web/templates/address_logs/_logs.html.eex:9
#: lib/block_scout_web/templates/transaction/_decoded_input.html.eex:11
-#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:22
+#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:9
msgid "here"
msgstr ""
@@ -1319,7 +1315,9 @@ msgid "To have guaranteed accuracy, use the link above to verify the contract's
msgstr ""
#, elixir-format
+#: lib/block_scout_web/templates/address_logs/_logs.html.eex:6
#: lib/block_scout_web/templates/transaction/_decoded_input.html.eex:8
+#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:6
msgid "To see accurate decoded input data, the contract must be verified."
msgstr ""
@@ -1778,9 +1776,11 @@ msgid "Constructor Arguments"
msgstr ""
#, elixir-format
-#: lib/block_scout_web/templates/address_logs/_logs.html.eex:63
+#: lib/block_scout_web/templates/address_logs/_logs.html.eex:66
+#: lib/block_scout_web/templates/address_logs/_logs.html.eex:119
#: lib/block_scout_web/templates/transaction/_decoded_input_body.html.eex:31
-#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:65
+#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:69
+#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:122
msgid "Copy Value"
msgstr ""
@@ -1790,29 +1790,35 @@ msgid "Create2"
msgstr ""
#, elixir-format
-#: lib/block_scout_web/templates/address_logs/_logs.html.eex:53
-#: lib/block_scout_web/templates/address_logs/_logs.html.eex:118
+#: lib/block_scout_web/templates/address_logs/_logs.html.eex:56
+#: lib/block_scout_web/templates/address_logs/_logs.html.eex:109
+#: lib/block_scout_web/templates/address_logs/_logs.html.eex:175
#: lib/block_scout_web/templates/transaction/_decoded_input_body.html.eex:21
-#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:55
-#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:121
+#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:59
+#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:112
+#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:179
msgid "Data"
msgstr ""
#, elixir-format
-#: lib/block_scout_web/templates/address_logs/_logs.html.eex:31
-#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:31
+#: lib/block_scout_web/templates/address_logs/_logs.html.eex:34
+#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:35
msgid "Failed to decode log data."
msgstr ""
#, elixir-format
-#: lib/block_scout_web/templates/address_logs/_logs.html.eex:52
-#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:54
+#: lib/block_scout_web/templates/address_logs/_logs.html.eex:55
+#: lib/block_scout_web/templates/address_logs/_logs.html.eex:108
+#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:58
+#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:111
msgid "Indexed?"
msgstr ""
#, elixir-format
-#: lib/block_scout_web/templates/address_logs/_logs.html.eex:47
-#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:49
+#: lib/block_scout_web/templates/address_logs/_logs.html.eex:50
+#: lib/block_scout_web/templates/address_logs/_logs.html.eex:103
+#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:53
+#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:106
msgid "Log Data"
msgstr ""
@@ -1824,14 +1830,16 @@ msgid "Reward"
msgstr ""
#, elixir-format
-#: lib/block_scout_web/templates/address_logs/_logs.html.eex:88
-#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:91
+#: lib/block_scout_web/templates/address_logs/_logs.html.eex:145
+#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:149
msgid "Topics"
msgstr ""
#, elixir-format
-#: lib/block_scout_web/templates/address_logs/_logs.html.eex:51
+#: lib/block_scout_web/templates/address_logs/_logs.html.eex:54
+#: lib/block_scout_web/templates/address_logs/_logs.html.eex:107
#: lib/block_scout_web/templates/transaction/_decoded_input_body.html.eex:20
-#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:53
+#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:57
+#: lib/block_scout_web/templates/transaction_log/_logs.html.eex:110
msgid "Type"
msgstr ""
diff --git a/apps/explorer/lib/explorer/chain/log.ex b/apps/explorer/lib/explorer/chain/log.ex
index b6c5c00a2d..7916b56fb3 100644
--- a/apps/explorer/lib/explorer/chain/log.ex
+++ b/apps/explorer/lib/explorer/chain/log.ex
@@ -6,7 +6,8 @@ defmodule Explorer.Chain.Log do
require Logger
alias ABI.{Event, FunctionSelector}
- alias Explorer.Chain.{Address, Data, Hash, Transaction}
+ alias Explorer.Chain.{Address, ContractMethod, Data, Hash, Transaction}
+ alias Explorer.Repo
@required_attrs ~w(address_hash data index transaction_hash)a
@optional_attrs ~w(first_topic second_topic third_topic fourth_topic type)a
@@ -114,7 +115,50 @@ defmodule Explorer.Chain.Log do
do: {:ok, identifier, text, mapping}
end
- def decode(_log, _transaction), do: {:error, :contract_not_verified}
+ def decode(log, transaction) do
+ case log.first_topic do
+ "0x" <> hex_part ->
+ case Integer.parse(hex_part, 16) do
+ {number, ""} ->
+ <> = :binary.encode_unsigned(number)
+ find_candidates(method_id, log, transaction)
+
+ _ ->
+ {:error, :could_not_decode}
+ end
+
+ _ ->
+ {:error, :could_not_decode}
+ end
+ end
+
+ defp find_candidates(method_id, log, transaction) do
+ candidates_query =
+ from(
+ contract_method in ContractMethod,
+ where: contract_method.identifier == ^method_id,
+ limit: 3
+ )
+
+ candidates =
+ candidates_query
+ |> Repo.all()
+ |> Enum.flat_map(fn contract_method ->
+ case find_and_decode([contract_method.abi], log, transaction) do
+ {:ok, selector, mapping} ->
+ identifier = Base.encode16(selector.method_id, case: :lower)
+ text = function_call(selector.function, mapping)
+
+ [{:ok, identifier, text, mapping}]
+
+ _ ->
+ []
+ end
+ end)
+ |> Enum.take(1)
+
+ {:error, :contract_not_verified, candidates}
+ end
defp find_and_decode(abi, log, transaction) do
with {%FunctionSelector{} = selector, mapping} <-
diff --git a/apps/explorer/test/explorer/chain/log_test.exs b/apps/explorer/test/explorer/chain/log_test.exs
index 28be44a1af..e4ce0695bc 100644
--- a/apps/explorer/test/explorer/chain/log_test.exs
+++ b/apps/explorer/test/explorer/chain/log_test.exs
@@ -2,7 +2,8 @@ defmodule Explorer.Chain.LogTest do
use Explorer.DataCase
alias Ecto.Changeset
- alias Explorer.Chain.Log
+ alias Explorer.Chain.{Log, SmartContract}
+ alias Explorer.Repo
doctest Log
@@ -47,7 +48,7 @@ defmodule Explorer.Chain.LogTest do
log = insert(:log, transaction: transaction)
- assert Log.decode(log, transaction) == {:error, :contract_not_verified}
+ assert Log.decode(log, transaction) == {:error, :could_not_decode}
end
test "that a contract call transaction that has a verified contract returns the decoded input data" do
@@ -100,5 +101,59 @@ defmodule Explorer.Chain.LogTest do
{"_belly", "bool", true, true}
]}
end
+
+ test "finds decoding candidates" do
+ params =
+ params_for(:smart_contract, %{
+ abi: [
+ %{
+ "anonymous" => false,
+ "inputs" => [
+ %{"indexed" => true, "name" => "_from_human", "type" => "string"},
+ %{"indexed" => false, "name" => "_number", "type" => "uint256"},
+ %{"indexed" => true, "name" => "_belly", "type" => "bool"}
+ ],
+ "name" => "WantsPets",
+ "type" => "event"
+ }
+ ]
+ })
+
+ # changeset has a callback to insert contract methods
+ %SmartContract{}
+ |> SmartContract.changeset(params)
+ |> Repo.insert!()
+
+ topic1 = "0x" <> Base.encode16(:keccakf1600.hash(:sha3_256, "WantsPets(string,uint256,bool)"), case: :lower)
+ topic2 = "0x" <> Base.encode16(:keccakf1600.hash(:sha3_256, "bob"), case: :lower)
+ topic3 = "0x0000000000000000000000000000000000000000000000000000000000000001"
+ data = "0x0000000000000000000000000000000000000000000000000000000000000000"
+
+ transaction = insert(:transaction)
+
+ log =
+ insert(:log,
+ transaction: transaction,
+ first_topic: topic1,
+ second_topic: topic2,
+ third_topic: topic3,
+ fourth_topic: nil,
+ data: data
+ )
+
+ assert Log.decode(log, transaction) ==
+ {:error, :contract_not_verified,
+ [
+ {:ok, "eb9b3c4c", "WantsPets(string indexed _from_human, uint256 _number, bool indexed _belly)",
+ [
+ {"_from_human", "string", true,
+ {:dynamic,
+ <<56, 228, 122, 123, 113, 157, 206, 99, 102, 42, 234, 244, 52, 64, 50, 111, 85, 27, 138, 126,
+ 225, 152, 206, 227, 92, 181, 213, 23, 242, 210, 150, 162>>}},
+ {"_number", "uint256", false, 0},
+ {"_belly", "bool", true, true}
+ ]}
+ ]}
+ end
end
end