Merge pull request #2555 from poanetwork/ab-decode-decoding-cadidates-for-logs

find decoding candidates for logs
pull/2646/head
Victor Baranov 5 years ago committed by GitHub
commit 130162d073
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      CHANGELOG.md
  2. 85
      apps/block_scout_web/lib/block_scout_web/templates/address_logs/_logs.html.eex
  3. 86
      apps/block_scout_web/lib/block_scout_web/templates/transaction_log/_logs.html.eex
  4. 80
      apps/block_scout_web/priv/gettext/default.pot
  5. 80
      apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po
  6. 48
      apps/explorer/lib/explorer/chain/log.ex
  7. 59
      apps/explorer/test/explorer/chain/log_test.exs

@ -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

@ -1,4 +1,19 @@
<div data-test="address_log" class="tile tile-muted" data-identifier-log="<%= "#{to_string(@log.transaction.hash)}#{@log.index}" %>">
<% decoded_result = decode(@log, @log.transaction) %>
<%= case decoded_result do %>
<%= {:error, :contract_not_verified, _cadidates} -> %>
<div class="alert alert-info">
<%= gettext "To see accurate decoded input data, the contract must be verified." %>
<%= case @log.transaction do %>
<% %{to_address: %{hash: hash}} -> %>
<%= gettext "Verify the contract " %><a href="<%= address_verify_contract_path(@conn, :new, hash)%>"><%= gettext "here" %></a>
<% _ -> %>
<%= nil %>
<% end %>
</div>
<% _ -> %>
<%= nil %>
<% end %>
<dl class="row">
<dt class="col-md-2"> <%= gettext "Transaction" %> </dt>
<dd class="col-md-10">
@ -11,19 +26,7 @@
) %>
</h3>
</dd>
<%= case decode(@log, @log.transaction) do %>
<% {:error, :contract_not_verified} -> %>
<dt class="col-md-2"><%= gettext "Decoded" %></dt>
<dd class="col-md-10">
<div class="alert alert-info">
<%= gettext "To see decoded input data, the contract must be verified." %>
<%= case @log.transaction do %>
<% %{to_address: %{hash: hash}} -> %>
<%= gettext "Verify the contract " %><a href="<%= address_verify_contract_path(@conn, :new, hash)%>"><%= gettext "here" %></a>
<% _ -> %>
<%= nil %>
<% end %>
</div>
<%= case decoded_result do %>
<% {:error, :could_not_decode} -> %>
<dt class="col-md-2"><%= gettext "Decoded" %></dt>
<dd class="col-md-10">
@ -81,7 +84,61 @@
</tr>
<% end %>
</table>
</div>
</div>
<% {:error, :contract_not_verified, results} -> %>
<%= for {:ok, method_id, text, mapping} <- results do %>
<dt class="col-md-2"><%= gettext "Decoded" %></dt>
<dd class="col-md-10">
<table summary="Transaction Info" class="table thead-light table-bordered transaction-input-table">
<tr>
<td>Method Id</td>
<td colspan="3"><code>0x<%= method_id %></code></td>
</tr>
<tr>
<td>Call</td>
<td colspan="3"><code><%= text %></code></td>
</tr>
</table>
<div class="table-responsive text-center">
<table style="color: black;" summary="<%= gettext "Log Data" %>" class="table thead-light table-bordered">
<tr>
<th scope="col"></th>
<th scope="col"><%= gettext "Name" %></th>
<th scope="col"><%= gettext "Type" %></th>
<th scope="col"><%= gettext "Indexed?" %></th>
<th scope="col"><%= gettext "Data" %></th>
<tr>
<%= for {name, type, indexed?, value} <- mapping do %>
<tr>
<th scope="row">
<%= case BlockScoutWeb.ABIEncodedValueView.copy_text(type, value) do %>
<% :error -> %>
<%= nil %>
<% copy_text -> %>
<span
aria-label='<%= gettext "Copy Value" %>'
class="btn-copy-ico"
data-clipboard-text="<%= copy_text %>"
data-placement="top"
data-toggle="tooltip"
>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32.5 32.5" width="32" height="32">
<path fill-rule="evenodd" d="M23.5 20.5a1 1 0 0 1-1-1v-9h-9a1 1 0 0 1 0-2h10a1 1 0 0 1 1 1v10a1 1 0 0 1-1 1zm-3-7v10a1 1 0 0 1-1 1h-10a1 1 0 0 1-1-1v-10a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1zm-2 1h-8v8h8v-8z"/>
</svg>
</span>
<% end %>
</th>
<td><%= name %></td>
<td><%= type %></td>
<td><%= indexed? %></td>
<td>
<pre class="transaction-input-text tile"><code><%= BlockScoutWeb.ABIEncodedValueView.value_html(type, value) %></code></pre>
</td>
</tr>
<% end %>
</table>
</div>
<% end %>
<% _ -> %>
<%= nil %>
<% end %>

@ -1,4 +1,20 @@
<div data-test="transaction_log" class="tile tile-muted">
<% decoded_result = decode(@log, @transaction) %>
<%= case decoded_result do %>
<%= {:error, :contract_not_verified, _cadidates} -> %>
<div class="alert alert-info">
<%= gettext "To see accurate decoded input data, the contract must be verified." %>
<%= case @transaction do %>
<% %{to_address: %{hash: hash}} -> %>
<%= gettext "Verify the contract " %><a href="<%= address_verify_contract_path(@conn, :new, hash)%>"><%= gettext "here" %></a>
<% _ -> %>
<%= nil %>
<% end %>
</div>
<% _ -> %>
<%= nil %>
<% end %>
<dl class="row">
<dt class="col-lg-2"> <%= gettext "Address" %> </dt>
<dd class="col-lg-10">
@ -11,19 +27,7 @@
) %>
</h3>
</dd>
<%= case decode(@log, @transaction) do %>
<% {:error, :contract_not_verified} -> %>
<dt class="col-lg-2"><%= gettext "Decoded" %></dt>
<dd class="col-lg-10">
<div class="alert alert-info">
<%= gettext "To see decoded input data, the contract must be verified." %>
<%= case @transaction do %>
<% %{to_address: %{hash: hash}} -> %>
<%= gettext "Verify the contract " %><a href="<%= address_verify_contract_path(@conn, :new, hash)%>"><%= gettext "here" %></a>
<% _ -> %>
<%= nil %>
<% end %>
</div>
<%= case decoded_result do %>
<% {:error, :could_not_decode} -> %>
<dt class="col-lg-2"><%= gettext "Decoded" %></dt>
<dd class="col-lg-10">
@ -83,7 +87,61 @@
</tr>
<% end %>
</table>
</div>
</div>
<% {:error, :contract_not_verified, results} -> %>
<%= for {:ok, method_id, text, mapping} <- results do %>
<dt class="col-md-2"><%= gettext "Decoded" %></dt>
<dd class="col-md-10">
<table summary="Transaction Info" class="table thead-light table-bordered transaction-input-table">
<tr>
<td>Method Id</td>
<td colspan="3"><code>0x<%= method_id %></code></td>
</tr>
<tr>
<td>Call</td>
<td colspan="3"><code><%= text %></code></td>
</tr>
</table>
<div class="table-responsive text-center">
<table style="color: black;" summary="<%= gettext "Log Data" %>" class="table thead-light table-bordered">
<tr>
<th scope="col"></th>
<th scope="col"><%= gettext "Name" %></th>
<th scope="col"><%= gettext "Type" %></th>
<th scope="col"><%= gettext "Indexed?" %></th>
<th scope="col"><%= gettext "Data" %></th>
<tr>
<%= for {name, type, indexed?, value} <- mapping do %>
<tr>
<th scope="row">
<%= case BlockScoutWeb.ABIEncodedValueView.copy_text(type, value) do %>
<% :error -> %>
<%= nil %>
<% copy_text -> %>
<span
aria-label='<%= gettext "Copy Value" %>'
class="btn-copy-ico"
data-clipboard-text="<%= copy_text %>"
data-placement="top"
data-toggle="tooltip"
>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32.5 32.5" width="32" height="32">
<path fill-rule="evenodd" d="M23.5 20.5a1 1 0 0 1-1-1v-9h-9a1 1 0 0 1 0-2h10a1 1 0 0 1 1 1v10a1 1 0 0 1-1 1zm-3-7v10a1 1 0 0 1-1 1h-10a1 1 0 0 1-1-1v-10a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1zm-2 1h-8v8h8v-8z"/>
</svg>
</span>
<% end %>
</th>
<td><%= name %></td>
<td><%= type %></td>
<td><%= indexed? %></td>
<td>
<pre class="transaction-input-text tile"><code><%= BlockScoutWeb.ABIEncodedValueView.value_html(type, value) %></code></pre>
</td>
</tr>
<% end %>
</table>
</div>
<% end %>
<% _ -> %>
<%= nil %>
<% end %>

@ -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 ""

@ -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 ""

@ -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, ""} ->
<<method_id::binary-size(4), _rest::binary>> = :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} <-

@ -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

Loading…
Cancel
Save