Merge pull request #6582 from blockscout/va-tx-actions

Transaction actions indexer
pull/6813/head
Victor Baranov 2 years ago committed by GitHub
commit 84b6c72f8d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      CHANGELOG.md
  2. 28
      apps/block_scout_web/assets/css/components/_transaction.scss
  3. 35
      apps/block_scout_web/assets/css/custom-scrollbar.scss
  4. 22
      apps/block_scout_web/assets/js/lib/custom_scrollbar.js
  5. 70
      apps/block_scout_web/assets/package-lock.json
  6. 1
      apps/block_scout_web/assets/package.json
  7. 2
      apps/block_scout_web/assets/webpack.config.js
  8. 2
      apps/block_scout_web/lib/block_scout_web/controllers/api/v2/transaction_controller.ex
  9. 7
      apps/block_scout_web/lib/block_scout_web/templates/layout/app.html.eex
  10. 62
      apps/block_scout_web/lib/block_scout_web/templates/transaction/_actions.html.eex
  11. 13
      apps/block_scout_web/lib/block_scout_web/templates/transaction/_actions_address.html.eex
  12. 4
      apps/block_scout_web/lib/block_scout_web/templates/transaction/_actions_to.html.eex
  13. 1
      apps/block_scout_web/lib/block_scout_web/templates/transaction/_actions_uniswap.html.eex
  14. 23
      apps/block_scout_web/lib/block_scout_web/templates/transaction/overview.html.eex
  15. 19
      apps/block_scout_web/lib/block_scout_web/views/api/v2/transaction_view.ex
  16. 18
      apps/block_scout_web/lib/block_scout_web/views/transaction_view.ex
  17. 345
      apps/block_scout_web/priv/gettext/default.pot
  18. 345
      apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po
  19. 75
      apps/explorer/lib/explorer/chain/import/runner/transaction_actions.ex
  20. 3
      apps/explorer/lib/explorer/chain/import/stage/block_referencing.ex
  21. 2
      apps/explorer/lib/explorer/chain/transaction.ex
  22. 70
      apps/explorer/lib/explorer/chain/transaction_action.ex
  23. 31
      apps/explorer/priv/repo/migrations/20221104091552_add_transaction_actions_table.exs
  24. 3
      apps/indexer/README.md
  25. 12
      apps/indexer/lib/indexer/block/fetcher.ex
  26. 283
      apps/indexer/lib/indexer/fetcher/transaction_action.ex
  27. 2
      apps/indexer/lib/indexer/supervisor.ex
  28. 39
      apps/indexer/lib/indexer/transform/addresses.ex
  29. 775
      apps/indexer/lib/indexer/transform/transaction_actions.ex
  30. 6
      apps/indexer/test/indexer/block/catchup/fetcher_test.exs
  31. 11
      config/runtime.exs
  32. 5
      docker-compose/envs/common-blockscout.env
  33. 21
      docker/Makefile

@ -9,6 +9,7 @@
- [#6721](https://github.com/blockscout/blockscout/pull/6721) - Implement fetching internal transactions from callTracer - [#6721](https://github.com/blockscout/blockscout/pull/6721) - Implement fetching internal transactions from callTracer
- [#6541](https://github.com/blockscout/blockscout/pull/6541) - Integrate sig provider - [#6541](https://github.com/blockscout/blockscout/pull/6541) - Integrate sig provider
- [#6712](https://github.com/blockscout/blockscout/pull/6712) - API v2 update - [#6712](https://github.com/blockscout/blockscout/pull/6712) - API v2 update
- [#6582](https://github.com/blockscout/blockscout/pull/6582) - Transaction actions indexer
### Fixes ### Fixes

@ -54,6 +54,34 @@
} }
} }
.actions-item {
margin-bottom: 4px;
display: inline-block;
i {
font-size: 10px;
}
&.subitem {
margin-left: 10px;
}
}
.actions-list-mobile-container {
@include media-breakpoint-down(sm) {
margin-top: 0.5rem;
}
}
#actions-list-scroll-note {
padding-left: 19px;
font-size: 11px;
display: none;
@media (max-width: $breakpoint-md) {
padding-left: 0;
}
}
.transfers-list-mobile-container { .transfers-list-mobile-container {
@include media-breakpoint-down(sm) { @include media-breakpoint-down(sm) {
margin-top: 0.5rem; margin-top: 0.5rem;

File diff suppressed because one or more lines are too long

@ -0,0 +1,22 @@
import $ from 'jquery'
import 'malihu-custom-scrollbar-plugin/jquery.mCustomScrollbar.concat.min'
$(function () {
const scrollBar = $('.mCustomScrollbar')
scrollBar.mCustomScrollbar({
callbacks: {
onOverflowY: () => {
$('#actions-list-scroll-note').css('display', 'block')
scrollBar.removeClass('mCS_no_scrollbar_y')
},
onOverflowYNone: () => {
$('#actions-list-scroll-note').css('display', 'none')
scrollBar.addClass('mCS_no_scrollbar_y')
}
},
theme: 'dark',
autoHideScrollbar: true,
scrollButtons: { enable: false },
scrollbarPosition: 'outside'
})
})

@ -45,6 +45,7 @@
"lodash.rangeright": "^4.2.0", "lodash.rangeright": "^4.2.0",
"lodash.reduce": "^4.6.0", "lodash.reduce": "^4.6.0",
"luxon": "^3.2.1", "luxon": "^3.2.1",
"malihu-custom-scrollbar-plugin": "3.1.5",
"mixpanel-browser": "^2.45.0", "mixpanel-browser": "^2.45.0",
"moment": "^2.29.4", "moment": "^2.29.4",
"nanomorph": "^5.4.0", "nanomorph": "^5.4.0",
@ -100,10 +101,11 @@
} }
}, },
"../../../deps/phoenix": { "../../../deps/phoenix": {
"version": "0.0.1" "version": "1.5.13",
"license": "MIT"
}, },
"../../../deps/phoenix_html": { "../../../deps/phoenix_html": {
"version": "0.0.1" "version": "3.0.4"
}, },
"node_modules/@amplitude/analytics-browser": { "node_modules/@amplitude/analytics-browser": {
"version": "1.7.0", "version": "1.7.0",
@ -11415,6 +11417,19 @@
"resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.3.tgz", "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.3.tgz",
"integrity": "sha512-bZ5Sy3YzKo9Fyc8wH2iIQK4JImJ6R0GWI9kL1/k7Z91ZBNgkRXE6U0JfHIizZbort8ZunhSI3jw9I6253ahKfg==" "integrity": "sha512-bZ5Sy3YzKo9Fyc8wH2iIQK4JImJ6R0GWI9kL1/k7Z91ZBNgkRXE6U0JfHIizZbort8ZunhSI3jw9I6253ahKfg=="
}, },
"node_modules/jquery-mousewheel": {
"version": "3.1.13",
"resolved": "https://registry.npmjs.org/jquery-mousewheel/-/jquery-mousewheel-3.1.13.tgz",
"integrity": "sha512-GXhSjfOPyDemM005YCEHvzrEALhKDIswtxSHSR2e4K/suHVJKJxxRCGz3skPjNxjJjQa9AVSGGlYjv1M3VLIPg=="
},
"node_modules/js-base64": {
"version": "2.6.4",
"resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.6.4.tgz",
"integrity": "sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ==",
"dev": true,
"optional": true,
"peer": true
},
"node_modules/js-cookie": { "node_modules/js-cookie": {
"version": "3.0.1", "version": "3.0.1",
"resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.1.tgz", "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.1.tgz",
@ -12074,6 +12089,28 @@
"tmpl": "1.0.5" "tmpl": "1.0.5"
} }
}, },
"node_modules/malihu-custom-scrollbar-plugin": {
"version": "3.1.5",
"resolved": "https://registry.npmjs.org/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-3.1.5.tgz",
"integrity": "sha512-lwW3LgI+CNDMPnP4ED2la6oYxWMkCXlnhex+s2wuOLhFDFGnGmQuTQVdRK9bvDLpxs10sGlfErVufJy9ztfgJQ==",
"dependencies": {
"jquery-mousewheel": ">=3.0.6"
}
},
"node_modules/map-obj": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz",
"integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==",
"dev": true,
"optional": true,
"peer": true,
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/md5.js": { "node_modules/md5.js": {
"version": "1.3.5", "version": "1.3.5",
"resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
@ -25616,6 +25653,19 @@
"resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.3.tgz", "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.3.tgz",
"integrity": "sha512-bZ5Sy3YzKo9Fyc8wH2iIQK4JImJ6R0GWI9kL1/k7Z91ZBNgkRXE6U0JfHIizZbort8ZunhSI3jw9I6253ahKfg==" "integrity": "sha512-bZ5Sy3YzKo9Fyc8wH2iIQK4JImJ6R0GWI9kL1/k7Z91ZBNgkRXE6U0JfHIizZbort8ZunhSI3jw9I6253ahKfg=="
}, },
"jquery-mousewheel": {
"version": "3.1.13",
"resolved": "https://registry.npmjs.org/jquery-mousewheel/-/jquery-mousewheel-3.1.13.tgz",
"integrity": "sha512-GXhSjfOPyDemM005YCEHvzrEALhKDIswtxSHSR2e4K/suHVJKJxxRCGz3skPjNxjJjQa9AVSGGlYjv1M3VLIPg=="
},
"js-base64": {
"version": "2.6.4",
"resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.6.4.tgz",
"integrity": "sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ==",
"dev": true,
"optional": true,
"peer": true
},
"js-cookie": { "js-cookie": {
"version": "3.0.1", "version": "3.0.1",
"resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.1.tgz", "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.1.tgz",
@ -26180,6 +26230,22 @@
"tmpl": "1.0.5" "tmpl": "1.0.5"
} }
}, },
"malihu-custom-scrollbar-plugin": {
"version": "3.1.5",
"resolved": "https://registry.npmjs.org/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-3.1.5.tgz",
"integrity": "sha512-lwW3LgI+CNDMPnP4ED2la6oYxWMkCXlnhex+s2wuOLhFDFGnGmQuTQVdRK9bvDLpxs10sGlfErVufJy9ztfgJQ==",
"requires": {
"jquery-mousewheel": ">=3.0.6"
}
},
"map-obj": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz",
"integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==",
"dev": true,
"optional": true,
"peer": true
},
"md5.js": { "md5.js": {
"version": "1.3.5", "version": "1.3.5",
"resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",

@ -57,6 +57,7 @@
"lodash.rangeright": "^4.2.0", "lodash.rangeright": "^4.2.0",
"lodash.reduce": "^4.6.0", "lodash.reduce": "^4.6.0",
"luxon": "^3.2.1", "luxon": "^3.2.1",
"malihu-custom-scrollbar-plugin": "3.1.5",
"mixpanel-browser": "^2.45.0", "mixpanel-browser": "^2.45.0",
"moment": "^2.29.4", "moment": "^2.29.4",
"nanomorph": "^5.4.0", "nanomorph": "^5.4.0",

@ -68,6 +68,8 @@ const appJs =
'text-ad': './js/lib/text_ad.js', 'text-ad': './js/lib/text_ad.js',
'banner': './js/lib/banner.js', 'banner': './js/lib/banner.js',
'autocomplete': './js/lib/autocomplete.js', 'autocomplete': './js/lib/autocomplete.js',
'custom-scrollbar': './js/lib/custom_scrollbar.js',
'custom-scrollbar-styles': './css/custom-scrollbar.scss',
'search-results': './js/pages/search-results/search.js', 'search-results': './js/pages/search-results/search.js',
'token-overview': './js/pages/token/overview.js', 'token-overview': './js/pages/token/overview.js',
'export-csv': './css/export-csv.scss', 'export-csv': './css/export-csv.scss',

@ -66,7 +66,7 @@ defmodule BlockScoutWeb.API.V2.TransactionController do
{:not_found, {:not_found,
Chain.hash_to_transaction( Chain.hash_to_transaction(
transaction_hash, transaction_hash,
necessity_by_association: @transaction_necessity_by_association necessity_by_association: Map.put(@transaction_necessity_by_association, :transaction_actions, :optional)
)}, )},
{:ok, false} <- AccessHelpers.restricted_access?(to_string(transaction.from_address_hash), params), {:ok, false} <- AccessHelpers.restricted_access?(to_string(transaction.from_address_hash), params),
{:ok, false} <- AccessHelpers.restricted_access?(to_string(transaction.to_address_hash), params), {:ok, false} <- AccessHelpers.restricted_access?(to_string(transaction.to_address_hash), params),

@ -11,6 +11,10 @@
<link rel="preload" href="<%= static_path(@conn, "/js/chain.js") %>" as="script"> <link rel="preload" href="<%= static_path(@conn, "/js/chain.js") %>" as="script">
<link rel="preload" href="<%= static_path(@conn, "/js/chart-loader.js") %>" as="script"> <link rel="preload" href="<%= static_path(@conn, "/js/chart-loader.js") %>" as="script">
<link rel="preload" href="<%= static_path(@conn, "/js/token-transfers-toggle.js") %>" as="script"> <link rel="preload" href="<%= static_path(@conn, "/js/token-transfers-toggle.js") %>" as="script">
<% Elixir.BlockScoutWeb.TransactionView -> %>
<link rel="stylesheet" href="<%= static_path(@conn, "/css/app.css") %>">
<link rel="stylesheet" href="<%= static_path(@conn, "/css/custom-scrollbar-styles.css") %>">
<link rel="preload" href="<%= static_path(@conn, "/js/custom-scrollbar.js") %>" as="script">
<% _ -> %> <% _ -> %>
<link rel="stylesheet" href="<%= static_path(@conn, "/css/app.css") %>"> <link rel="stylesheet" href="<%= static_path(@conn, "/css/app.css") %>">
<% end %> <% end %>
@ -238,6 +242,9 @@
<script defer data-cfasync="false" src="<%= static_path(@conn, "/js/chart-loader.js") %>"></script> <script defer data-cfasync="false" src="<%= static_path(@conn, "/js/chart-loader.js") %>"></script>
<script defer data-cfasync="false" src="<%= static_path(@conn, "/js/token-transfers-toggle.js") %>"></script> <script defer data-cfasync="false" src="<%= static_path(@conn, "/js/token-transfers-toggle.js") %>"></script>
<% end %> <% end %>
<%= if @view_module == Elixir.BlockScoutWeb.TransactionView do %>
<script defer data-cfasync="false" src="<%= static_path(@conn, "/js/custom-scrollbar.js") %>"></script>
<% end %>
<script defer src="<%= static_path(@conn, "/js/autocomplete.js") %>"></script> <script defer src="<%= static_path(@conn, "/js/autocomplete.js") %>"></script>
<%= if @view_module in [Elixir.BlockScoutWeb.AddressContractVerificationView, Elixir.BlockScoutWeb.AddressContractVerificationVyperView, Elixir.BlockScoutWeb.AddressContractVerificationViaFlattenedCodeView, Elixir.BlockScoutWeb.AddressContractVerificationViaMultiPartFilesView, Elixir.BlockScoutWeb.AddressContractVerificationViaJsonView, Elixir.BlockScoutWeb.AddressContractVerificationViaStandardJsonInputView] do %> <%= if @view_module in [Elixir.BlockScoutWeb.AddressContractVerificationView, Elixir.BlockScoutWeb.AddressContractVerificationVyperView, Elixir.BlockScoutWeb.AddressContractVerificationViaFlattenedCodeView, Elixir.BlockScoutWeb.AddressContractVerificationViaMultiPartFilesView, Elixir.BlockScoutWeb.AddressContractVerificationViaJsonView, Elixir.BlockScoutWeb.AddressContractVerificationViaStandardJsonInputView] do %>
<script defer data-cfasync="false" src="<%= static_path(@conn, "/js/verification-form.js") %>"></script> <script defer data-cfasync="false" src="<%= static_path(@conn, "/js/verification-form.js") %>"></script>

@ -0,0 +1,62 @@
<%= if @action.protocol == :uniswap_v3 do %>
<%= if @action.type == :mint_nft do %>
<div class="<%= if @isLast, do: "lastItem", else: "" %>">
<span class="actions-item">
<i class="fa fa-caret-right"></i>
<% address_string = Map.get(@action.data, "address") %>
<% {address_status, address} = transaction_action_string_to_address(address_string) %>
<% address = if address_status == :ok, do: render_to_string(BlockScoutWeb.AddressView, "_link.html", address: address, contract: BlockScoutWeb.AddressView.contract?(address), use_custom_tooltip: false, trimmed: false), else: render_to_string(BlockScoutWeb.TransactionView, "_actions_address.html", address_string: address_string, action: @action) %>
<% to_address = Map.get(@action.data, "to") %>
<% to_content = raw(render_to_string BlockScoutWeb.TransactionView, "_actions_to.html", address: to_address) %>
<% to = link to: address_path(BlockScoutWeb.Endpoint, :show, to_address), "data-test": "address_hash_link", do: to_content %>
<%= gettext("Mint of %{address} <span class=\"text-muted\">To</span> %{to}", address: address, to: safe_to_string(to)) |> raw() %>
</span>
<br />
<% token_ids = Map.get(@action.data, "ids") %>
<%= for id <- token_ids do %>
<span class="actions-item subitem">
<i class="fa fa-caret-right"></i>
<% link_to_id = link id, to: token_instance_path(BlockScoutWeb.Endpoint, :show, address_string, id), "data-test": "token_link" %>
<%= gettext("%{qty} of <span class=\"text-muted\">Token ID [%{link_to_id}]</span>", qty: 1, link_to_id: safe_to_string(link_to_id)) |> raw() %>
</span>
<br />
<% end %>
</div>
<% end %>
<%= if Enum.member?([:mint, :burn, :collect, :swap], @action.type) do %>
<div class="<%= if @isLast, do: "lastItem", else: "" %>">
<span class="actions-item">
<% amount0 = formatted_action_amount(@action.data, "amount0") %>
<% amount1 = formatted_action_amount(@action.data, "amount1") %>
<% symbol0 = Map.get(@action.data, "symbol0") %>
<% address0 = Map.get(@action.data, "address0") %>
<% symbol1 = Map.get(@action.data, "symbol1") %>
<% address1 = Map.get(@action.data, "address1") %>
<i class="fa fa-caret-right"></i>
<% symbol0 = if symbol0 != "Ether", do: link(symbol0, to: token_path(BlockScoutWeb.Endpoint, :show, address0), "data-test": "token_link"), else: raw(symbol0) %>
<% symbol1 = if symbol1 != "Ether", do: link(symbol1, to: token_path(BlockScoutWeb.Endpoint, :show, address1), "data-test": "token_link"), else: raw(symbol1) %>
<%= if @action.type == :mint do %>
<%= render BlockScoutWeb.TransactionView, "_actions_uniswap.html", action: "Add", amount0: amount0, symbol0: symbol0, conjunction: "And", amount1: amount1, symbol1: symbol1, tail: "Liquidity To Uniswap V3" %>
<% end %>
<%= if @action.type == :burn do %>
<%= render BlockScoutWeb.TransactionView, "_actions_uniswap.html", action: "Remove", amount0: amount0, symbol0: symbol0, conjunction: "And", amount1: amount1, symbol1: symbol1, tail: "Liquidity From Uniswap V3" %>
<% end %>
<%= if @action.type == :collect do %>
<%= render BlockScoutWeb.TransactionView, "_actions_uniswap.html", action: "Collect", amount0: amount0, symbol0: symbol0, conjunction: "And", amount1: amount1, symbol1: symbol1, tail: "From Uniswap V3" %>
<% end %>
<%= if @action.type == :swap do %>
<%= render BlockScoutWeb.TransactionView, "_actions_uniswap.html", action: "Swap", amount0: amount0, symbol0: symbol0, conjunction: "For", amount1: amount1, symbol1: symbol1, tail: "On Uniswap V3" %>
<% end %>
</span>
<br />
</div>
<% end %>
<% end %>

@ -0,0 +1,13 @@
<%= link to: address_path(BlockScoutWeb.Endpoint, :show, @address_string), "data-test": "address_hash_link" do %>
<% name = Map.get(@action.data, "name") %>
<span data-toggle="tooltip" data-placement="top" title="<%= name %>">
<span class="d-none d-md-none d-lg-inline d-xl-inline"><%= AddressView.short_string(name, 15) %></span>
<span class="d-inline d-md-inline d-lg-none d-xl-none"><%= AddressView.short_string(name, 5) %></span>
</span>
<% symbol = Map.get(@action.data, "symbol") %>
<span data-toggle="tooltip" data-placement="top" title="<%= symbol %>">
<span class="d-none d-md-none d-lg-inline d-xl-inline">(<%= AddressView.short_string(symbol, 15) %>)</span>
<span class="d-inline d-md-inline d-lg-none d-xl-none">(<%= AddressView.short_string(symbol, 5) %>)</span>
</span>
<% end %>

@ -0,0 +1,4 @@
<span data-toggle="tooltip" data-placement="top" title="<%= @address %>">
<span class="d-none d-md-none d-xl-inline"><%= @address %></span>
<span class="d-md-inline-block d-xl-none"><%= BlockScoutWeb.AddressView.trimmed_hash(@address) %></span>
</span>

@ -0,0 +1 @@
<span class="text-muted"><%= @action %></span> <%= @amount0 %> <%= @symbol0 %> <span class="text-muted"><%= @conjunction %></span> <%= @amount1 %> <%= @symbol1 %> <span class="text-muted"><%= @tail %></span>

@ -192,6 +192,29 @@
</dd> </dd>
</dl> </dl>
<% end %> <% end %>
<!-- Transaction Action -->
<% %{transaction_actions: transaction_actions} = transaction_actions(@transaction) %>
<%= if not Enum.empty?(transaction_actions) do %>
<dl class="row">
<dt class="col-sm-3 col-lg-2 text-muted">
<%= render BlockScoutWeb.CommonComponentsView, "_i_tooltip_2.html",
text: gettext("Highlighted events of the transaction.") %>
<%= gettext "Transaction Action" %>
<p id="actions-list-scroll-note"><%= gettext "Scroll to see more" %></p>
</dt>
<dd class="col-sm-9 col-lg-10 actions-list-mobile-container">
<div class="mCustomScrollbar" style="max-height:100px;width:90%">
<% transaction_actions_indexed = Enum.with_index(transaction_actions) %>
<% transaction_actions_length = Enum.count(transaction_actions) %>
<%= for {action, i} <- transaction_actions_indexed do %>
<% action_assigns = Map.put(assigns, :action, action) %>
<% action_assigns = Map.put(action_assigns, :isLast, (i == transaction_actions_length - 1)) %>
<%= render BlockScoutWeb.TransactionView, "_actions.html", action_assigns %>
<% end %>
</div>
</dd>
</dl>
<% end %>
<!-- From --> <!-- From -->
<dl class="row"> <dl class="row">
<dt class="col-sm-3 col-lg-2 text-muted"> <dt class="col-sm-3 col-lg-2 text-muted">

@ -59,6 +59,10 @@ defmodule BlockScoutWeb.API.V2.TransactionView do
prepare_token_transfer(token_transfer, conn) prepare_token_transfer(token_transfer, conn)
end end
def render("transaction_actions.json", %{actions: actions}) do
Enum.map(actions, &prepare_transaction_action(&1))
end
def render("internal_transactions.json", %{ def render("internal_transactions.json", %{
internal_transactions: internal_transactions, internal_transactions: internal_transactions,
next_page_params: next_page_params, next_page_params: next_page_params,
@ -102,6 +106,14 @@ defmodule BlockScoutWeb.API.V2.TransactionView do
} }
end end
def prepare_transaction_action(action) do
%{
"protocol" => action.protocol,
"type" => action.type,
"data" => action.data
}
end
def prepare_token_transfer_total(token_transfer) do def prepare_token_transfer_total(token_transfer) do
case Helpers.token_transfer_amount_for_api(token_transfer) do case Helpers.token_transfer_amount_for_api(token_transfer) do
{:ok, :erc721_instance} -> {:ok, :erc721_instance} ->
@ -244,6 +256,7 @@ defmodule BlockScoutWeb.API.V2.TransactionView do
"decoded_input" => decoded_input_data, "decoded_input" => decoded_input_data,
"token_transfers" => token_transfers(transaction.token_transfers, conn, single_tx?), "token_transfers" => token_transfers(transaction.token_transfers, conn, single_tx?),
"token_transfers_overflow" => token_transfers_overflow(transaction.token_transfers, single_tx?), "token_transfers_overflow" => token_transfers_overflow(transaction.token_transfers, single_tx?),
"actions" => transaction_actions(transaction.transaction_actions),
"exchange_rate" => (Market.get_exchange_rate(Explorer.coin()) || TokenRate.null()).usd_value, "exchange_rate" => (Market.get_exchange_rate(Explorer.coin()) || TokenRate.null()).usd_value,
"method" => method_name(transaction, decoded_input), "method" => method_name(transaction, decoded_input),
"tx_types" => tx_types(transaction), "tx_types" => tx_types(transaction),
@ -267,6 +280,12 @@ defmodule BlockScoutWeb.API.V2.TransactionView do
def token_transfers_overflow(token_transfers, _), def token_transfers_overflow(token_transfers, _),
do: Enum.count(token_transfers) > Chain.get_token_transfers_per_transaction_preview_count() do: Enum.count(token_transfers) > Chain.get_token_transfers_per_transaction_preview_count()
defp transaction_actions(%NotLoaded{}), do: []
defp transaction_actions(actions) do
render("transaction_actions.json", %{actions: actions})
end
defp priority_fee_per_gas(max_priority_fee_per_gas, base_fee_per_gas, max_fee_per_gas) do defp priority_fee_per_gas(max_priority_fee_per_gas, base_fee_per_gas, max_fee_per_gas) do
if is_nil(max_priority_fee_per_gas) or is_nil(base_fee_per_gas), if is_nil(max_priority_fee_per_gas) or is_nil(base_fee_per_gas),
do: nil, do: nil,

@ -62,6 +62,10 @@ defmodule BlockScoutWeb.TransactionView do
if type, do: {type, transaction_with_transfers_filtered}, else: {nil, transaction_with_transfers_filtered} if type, do: {type, transaction_with_transfers_filtered}, else: {nil, transaction_with_transfers_filtered}
end end
def transaction_actions(transaction) do
Repo.preload(transaction, :transaction_actions)
end
def aggregate_token_transfers(token_transfers) do def aggregate_token_transfers(token_transfers) do
%{ %{
transfers: {ft_transfers, nft_transfers}, transfers: {ft_transfers, nft_transfers},
@ -318,6 +322,20 @@ defmodule BlockScoutWeb.TransactionView do
end end
end end
def formatted_action_amount(data, field_name) do
data
|> Map.get(field_name)
|> Decimal.new()
|> BlockScoutWeb.CldrHelper.Number.to_string!(format: "#,##0.##################")
end
def transaction_action_string_to_address(address) do
case Chain.string_to_address_hash(address) do
{:ok, address_hash} -> Chain.hash_to_address(address_hash)
_ -> {:error, nil}
end
end
def transaction_status(transaction) do def transaction_status(transaction) do
Chain.transaction_to_status(transaction) Chain.transaction_to_status(transaction)
end end

@ -63,7 +63,7 @@ msgstr ""
msgid "%{subnetwork} Explorer - BlockScout" msgid "%{subnetwork} Explorer - BlockScout"
msgstr "" msgstr ""
#: lib/block_scout_web/views/transaction_view.ex:347 #: lib/block_scout_web/views/transaction_view.ex:365
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "(Awaiting internal transactions for status)" msgid "(Awaiting internal transactions for status)"
msgstr "" msgstr ""
@ -81,31 +81,11 @@ msgstr ""
msgid ") may be added for each contract. Click the Add Library button to add an additional one." msgid ") may be added for each contract. Click the Add Library button to add an additional one."
msgstr "" msgstr ""
#: lib/block_scout_web/templates/layout/app.html.eex:171 #: lib/block_scout_web/templates/layout/app.html.eex:175
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "- We're indexing this chain right now. Some of the counts may be inaccurate." msgid "- We're indexing this chain right now. Some of the counts may be inaccurate."
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/not_found.html.eex:8
#, elixir-autogen, elixir-format
msgid "1. If you have just submitted this transaction please wait for at least 30 seconds before refreshing this page."
msgstr ""
#: lib/block_scout_web/templates/transaction/not_found.html.eex:9
#, elixir-autogen, elixir-format
msgid "2. It could still be in the TX Pool of a different node, waiting to be broadcasted."
msgstr ""
#: lib/block_scout_web/templates/transaction/not_found.html.eex:10
#, elixir-autogen, elixir-format
msgid "3. During times when the network is busy (i.e during ICOs) it can take a while for your transaction to propagate through the network and for us to index it."
msgstr ""
#: lib/block_scout_web/templates/transaction/not_found.html.eex:11
#, elixir-autogen, elixir-format
msgid "4. If it still does not show up after 1 hour, please check with your sender/exchange/wallet/transaction provider for additional information."
msgstr ""
#: lib/block_scout_web/templates/block/overview.html.eex:195 #: lib/block_scout_web/templates/block/overview.html.eex:195
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "64-bit hash of value verifying proof-of-work (note: null for POA chains)." msgid "64-bit hash of value verifying proof-of-work (note: null for POA chains)."
@ -189,7 +169,7 @@ msgstr ""
msgid "Actions" msgid "Actions"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:425 #: lib/block_scout_web/templates/transaction/overview.html.eex:448
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Actual gas amount used by the transaction." msgid "Actual gas amount used by the transaction."
msgstr "" msgstr ""
@ -259,12 +239,12 @@ msgstr ""
msgid "Address" msgid "Address"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:217 #: lib/block_scout_web/templates/transaction/overview.html.eex:240
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Address (external or contract) receiving the transaction." msgid "Address (external or contract) receiving the transaction."
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:199 #: lib/block_scout_web/templates/transaction/overview.html.eex:222
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Address (external or contract) sending the transaction." msgid "Address (external or contract) sending the transaction."
msgstr "" msgstr ""
@ -329,7 +309,7 @@ msgstr ""
msgid "All tokens in the account and total value." msgid "All tokens in the account and total value."
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:411 #: lib/block_scout_web/templates/transaction/overview.html.eex:434
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Amount of" msgid "Amount of"
msgstr "" msgstr ""
@ -339,11 +319,6 @@ msgstr ""
msgid "Amount of distributed reward. Miners receive a static block reward + Tx fees + uncle fees." msgid "Amount of distributed reward. Miners receive a static block reward + Tx fees + uncle fees."
msgstr "" msgstr ""
#: lib/block_scout_web/templates/internal_server_error/index.html.eex:8
#, elixir-autogen, elixir-format
msgid "An unexpected error has occurred. Try reloading the page, or come back soon and try again."
msgstr ""
#: lib/block_scout_web/templates/api_docs/eth_rpc.html.eex:15 #: lib/block_scout_web/templates/api_docs/eth_rpc.html.eex:15
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Anything not in this list is not supported. Click on the method to be taken to the documentation for that method, and check the notes section for any potential differences." msgid "Anything not in this list is not supported. Click on the method to be taken to the documentation for that method, and check the notes section for any potential differences."
@ -389,14 +364,6 @@ msgstr ""
msgid "Back to Watch list (Cancel)" msgid "Back to Watch list (Cancel)"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/error422/index.html.eex:9
#: lib/block_scout_web/templates/internal_server_error/index.html.eex:9
#: lib/block_scout_web/templates/page_not_found/index.html.eex:9
#: lib/block_scout_web/templates/transaction/not_found.html.eex:13
#, elixir-autogen, elixir-format
msgid "Back to home"
msgstr ""
#: lib/block_scout_web/templates/account/watchlist/show.html.eex:24 #: lib/block_scout_web/templates/account/watchlist/show.html.eex:24
#: lib/block_scout_web/templates/address/overview.html.eex:150 #: lib/block_scout_web/templates/address/overview.html.eex:150
#: lib/block_scout_web/templates/address_token/overview.html.eex:51 #: lib/block_scout_web/templates/address_token/overview.html.eex:51
@ -431,7 +398,7 @@ msgstr ""
msgid "Base URL:" msgid "Base URL:"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:446 #: lib/block_scout_web/templates/transaction/overview.html.eex:469
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Binary data included with the transaction. See input / logs below for additional info." msgid "Binary data included with the transaction. See input / logs below for additional info."
msgstr "" msgstr ""
@ -465,7 +432,7 @@ msgstr ""
msgid "Block Height" msgid "Block Height"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/layout/app.html.eex:43 #: lib/block_scout_web/templates/layout/app.html.eex:47
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Block Mined, awaiting import..." msgid "Block Mined, awaiting import..."
msgstr "" msgstr ""
@ -512,7 +479,7 @@ msgstr ""
msgid "Blocks" msgid "Blocks"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/layout/app.html.eex:42 #: lib/block_scout_web/templates/layout/app.html.eex:46
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Blocks Indexed" msgid "Blocks Indexed"
msgstr "" msgstr ""
@ -525,7 +492,7 @@ msgstr ""
msgid "Blocks Validated" msgid "Blocks Validated"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/layout/app.html.eex:44 #: lib/block_scout_web/templates/layout/app.html.eex:48
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Blocks With Internal Transactions Indexed" msgid "Blocks With Internal Transactions Indexed"
msgstr "" msgstr ""
@ -657,7 +624,7 @@ msgstr ""
msgid "Compiler version" msgid "Compiler version"
msgstr "" msgstr ""
#: lib/block_scout_web/views/transaction_view.ex:340 #: lib/block_scout_web/views/transaction_view.ex:358
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Confirmed" msgid "Confirmed"
msgstr "" msgstr ""
@ -717,7 +684,7 @@ msgid "Constructor args"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:52 #: lib/block_scout_web/templates/tokens/overview/_details.html.eex:52
#: lib/block_scout_web/templates/transaction/overview.html.eex:227 #: lib/block_scout_web/templates/transaction/overview.html.eex:250
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Contract" msgid "Contract"
msgstr "" msgstr ""
@ -742,12 +709,12 @@ msgstr ""
msgid "Contract Address Pending" msgid "Contract Address Pending"
msgstr "" msgstr ""
#: lib/block_scout_web/views/transaction_view.ex:455 #: lib/block_scout_web/views/transaction_view.ex:473
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Contract Call" msgid "Contract Call"
msgstr "" msgstr ""
#: lib/block_scout_web/views/transaction_view.ex:452 #: lib/block_scout_web/views/transaction_view.ex:470
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Contract Creation" msgid "Contract Creation"
msgstr "" msgstr ""
@ -868,8 +835,8 @@ msgstr ""
#: lib/block_scout_web/templates/account/watchlist_address/row.html.eex:7 #: lib/block_scout_web/templates/account/watchlist_address/row.html.eex:7
#: lib/block_scout_web/templates/transaction/_total_transfers_from_to.html.eex:17 #: lib/block_scout_web/templates/transaction/_total_transfers_from_to.html.eex:17
#: lib/block_scout_web/templates/transaction/_total_transfers_from_to.html.eex:18 #: lib/block_scout_web/templates/transaction/_total_transfers_from_to.html.eex:18
#: lib/block_scout_web/templates/transaction/overview.html.eex:207 #: lib/block_scout_web/templates/transaction/overview.html.eex:230
#: lib/block_scout_web/templates/transaction/overview.html.eex:208 #: lib/block_scout_web/templates/transaction/overview.html.eex:231
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Copy From Address" msgid "Copy From Address"
msgstr "" msgstr ""
@ -904,10 +871,10 @@ msgstr ""
#: lib/block_scout_web/templates/transaction/_total_transfers_from_to.html.eex:34 #: lib/block_scout_web/templates/transaction/_total_transfers_from_to.html.eex:34
#: lib/block_scout_web/templates/transaction/_total_transfers_from_to.html.eex:35 #: lib/block_scout_web/templates/transaction/_total_transfers_from_to.html.eex:35
#: lib/block_scout_web/templates/transaction/overview.html.eex:234 #: lib/block_scout_web/templates/transaction/overview.html.eex:257
#: lib/block_scout_web/templates/transaction/overview.html.eex:235 #: lib/block_scout_web/templates/transaction/overview.html.eex:258
#: lib/block_scout_web/templates/transaction/overview.html.eex:242 #: lib/block_scout_web/templates/transaction/overview.html.eex:265
#: lib/block_scout_web/templates/transaction/overview.html.eex:243 #: lib/block_scout_web/templates/transaction/overview.html.eex:266
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Copy To Address" msgid "Copy To Address"
msgstr "" msgstr ""
@ -928,20 +895,20 @@ msgstr ""
msgid "Copy Txn Hash" msgid "Copy Txn Hash"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:472 #: lib/block_scout_web/templates/transaction/overview.html.eex:495
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Copy Txn Hex Input" msgid "Copy Txn Hex Input"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:478 #: lib/block_scout_web/templates/transaction/overview.html.eex:501
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Copy Txn UTF-8 Input" msgid "Copy Txn UTF-8 Input"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/log/_data_decoded_view.html.eex:20 #: lib/block_scout_web/templates/log/_data_decoded_view.html.eex:20
#: lib/block_scout_web/templates/transaction/_decoded_input_body.html.eex:41 #: lib/block_scout_web/templates/transaction/_decoded_input_body.html.eex:41
#: lib/block_scout_web/templates/transaction/overview.html.eex:471 #: lib/block_scout_web/templates/transaction/overview.html.eex:494
#: lib/block_scout_web/templates/transaction/overview.html.eex:477 #: lib/block_scout_web/templates/transaction/overview.html.eex:500
#: lib/block_scout_web/templates/transaction_raw_trace/index.html.eex:14 #: lib/block_scout_web/templates/transaction_raw_trace/index.html.eex:14
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Copy Value" msgid "Copy Value"
@ -1144,12 +1111,12 @@ msgstr ""
msgid "EIP-1167" msgid "EIP-1167"
msgstr "" msgstr ""
#: lib/block_scout_web/views/transaction_view.ex:212 #: lib/block_scout_web/views/transaction_view.ex:216
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "ERC-1155 " msgid "ERC-1155 "
msgstr "" msgstr ""
#: lib/block_scout_web/views/transaction_view.ex:210 #: lib/block_scout_web/views/transaction_view.ex:214
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "ERC-20 " msgid "ERC-20 "
msgstr "" msgstr ""
@ -1159,7 +1126,7 @@ msgstr ""
msgid "ERC-20 tokens (beta)" msgid "ERC-20 tokens (beta)"
msgstr "" msgstr ""
#: lib/block_scout_web/views/transaction_view.ex:211 #: lib/block_scout_web/views/transaction_view.ex:215
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "ERC-721 " msgid "ERC-721 "
msgstr "" msgstr ""
@ -1250,12 +1217,12 @@ msgstr ""
msgid "Error trying to fetch balances." msgid "Error trying to fetch balances."
msgstr "" msgstr ""
#: lib/block_scout_web/views/transaction_view.ex:351 #: lib/block_scout_web/views/transaction_view.ex:369
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Error: %{reason}" msgid "Error: %{reason}"
msgstr "" msgstr ""
#: lib/block_scout_web/views/transaction_view.ex:349 #: lib/block_scout_web/views/transaction_view.ex:367
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Error: (Awaiting internal transactions for reason)" msgid "Error: (Awaiting internal transactions for reason)"
msgstr "" msgstr ""
@ -1369,7 +1336,7 @@ msgstr ""
#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:38 #: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:38
#: lib/block_scout_web/templates/address_token_transfer/index.html.eex:40 #: lib/block_scout_web/templates/address_token_transfer/index.html.eex:40
#: lib/block_scout_web/templates/address_transaction/index.html.eex:34 #: lib/block_scout_web/templates/address_transaction/index.html.eex:34
#: lib/block_scout_web/templates/transaction/overview.html.eex:200 #: lib/block_scout_web/templates/transaction/overview.html.eex:223
#: lib/block_scout_web/views/address_internal_transaction_view.ex:10 #: lib/block_scout_web/views/address_internal_transaction_view.ex:10
#: lib/block_scout_web/views/address_token_transfer_view.ex:10 #: lib/block_scout_web/views/address_token_transfer_view.ex:10
#: lib/block_scout_web/views/address_transaction_view.ex:10 #: lib/block_scout_web/views/address_transaction_view.ex:10
@ -1384,12 +1351,12 @@ msgstr ""
#: lib/block_scout_web/templates/block/_tile.html.eex:67 #: lib/block_scout_web/templates/block/_tile.html.eex:67
#: lib/block_scout_web/templates/block/overview.html.eex:187 #: lib/block_scout_web/templates/block/overview.html.eex:187
#: lib/block_scout_web/templates/transaction/overview.html.eex:373 #: lib/block_scout_web/templates/transaction/overview.html.eex:396
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Gas Limit" msgid "Gas Limit"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:353 #: lib/block_scout_web/templates/transaction/overview.html.eex:376
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Gas Price" msgid "Gas Price"
msgstr "" msgstr ""
@ -1401,7 +1368,7 @@ msgstr ""
msgid "Gas Used" msgid "Gas Used"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:426 #: lib/block_scout_web/templates/transaction/overview.html.eex:449
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Gas Used by Transaction" msgid "Gas Used by Transaction"
msgstr "" msgstr ""
@ -1453,8 +1420,8 @@ msgstr ""
msgid "Hash" msgid "Hash"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:454 #: lib/block_scout_web/templates/transaction/overview.html.eex:477
#: lib/block_scout_web/templates/transaction/overview.html.eex:458 #: lib/block_scout_web/templates/transaction/overview.html.eex:481
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Hex (Default)" msgid "Hex (Default)"
msgstr "" msgstr ""
@ -1508,7 +1475,7 @@ msgstr ""
msgid "Incoming" msgid "Incoming"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:438 #: lib/block_scout_web/templates/transaction/overview.html.eex:461
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Index position of Transaction in the block." msgid "Index position of Transaction in the block."
msgstr "" msgstr ""
@ -1528,7 +1495,7 @@ msgstr ""
msgid "Input" msgid "Input"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:219 #: lib/block_scout_web/templates/transaction/overview.html.eex:242
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Interacted With (To)" msgid "Interacted With (To)"
msgstr "" msgstr ""
@ -1543,16 +1510,11 @@ msgstr ""
#: lib/block_scout_web/templates/transaction/_tabs.html.eex:11 #: lib/block_scout_web/templates/transaction/_tabs.html.eex:11
#: lib/block_scout_web/templates/transaction_internal_transaction/index.html.eex:6 #: lib/block_scout_web/templates/transaction_internal_transaction/index.html.eex:6
#: lib/block_scout_web/views/address_view.ex:371 #: lib/block_scout_web/views/address_view.ex:371
#: lib/block_scout_web/views/transaction_view.ex:510 #: lib/block_scout_web/views/transaction_view.ex:528
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Internal Transactions" msgid "Internal Transactions"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/internal_server_error/index.html.eex:7
#, elixir-autogen, elixir-format
msgid "Internal server error"
msgstr ""
#: lib/block_scout_web/templates/tokens/inventory/index.html.eex:16 #: lib/block_scout_web/templates/tokens/inventory/index.html.eex:16
#: lib/block_scout_web/templates/tokens/overview/_tabs.html.eex:19 #: lib/block_scout_web/templates/tokens/overview/_tabs.html.eex:19
#: lib/block_scout_web/views/tokens/overview_view.ex:42 #: lib/block_scout_web/views/tokens/overview_view.ex:42
@ -1582,7 +1544,7 @@ msgstr ""
msgid "Learn more" msgid "Learn more"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/layout/app.html.eex:45 #: lib/block_scout_web/templates/layout/app.html.eex:49
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Less than" msgid "Less than"
msgstr "" msgstr ""
@ -1603,22 +1565,22 @@ msgstr ""
msgid "License ID" msgid "License ID"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:305 #: lib/block_scout_web/templates/transaction/overview.html.eex:328
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "List of ERC-1155 tokens created in the transaction." msgid "List of ERC-1155 tokens created in the transaction."
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:289 #: lib/block_scout_web/templates/transaction/overview.html.eex:312
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "List of token burnt in the transaction." msgid "List of token burnt in the transaction."
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:272 #: lib/block_scout_web/templates/transaction/overview.html.eex:295
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "List of token minted in the transaction." msgid "List of token minted in the transaction."
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:256 #: lib/block_scout_web/templates/transaction/overview.html.eex:279
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "List of token transferred in the transaction." msgid "List of token transferred in the transaction."
msgstr "" msgstr ""
@ -1660,7 +1622,7 @@ msgstr ""
#: lib/block_scout_web/templates/transaction/_tabs.html.eex:17 #: lib/block_scout_web/templates/transaction/_tabs.html.eex:17
#: lib/block_scout_web/templates/transaction_log/index.html.eex:8 #: lib/block_scout_web/templates/transaction_log/index.html.eex:8
#: lib/block_scout_web/views/address_view.ex:382 #: lib/block_scout_web/views/address_view.ex:382
#: lib/block_scout_web/views/transaction_view.ex:511 #: lib/block_scout_web/views/transaction_view.ex:529
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Logs" msgid "Logs"
msgstr "" msgstr ""
@ -1671,7 +1633,7 @@ msgid "Main Networks"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/chain/show.html.eex:52 #: lib/block_scout_web/templates/chain/show.html.eex:52
#: lib/block_scout_web/templates/layout/app.html.eex:46 #: lib/block_scout_web/templates/layout/app.html.eex:50
#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:84 #: lib/block_scout_web/templates/tokens/overview/_details.html.eex:84
#: lib/block_scout_web/views/address_view.ex:145 #: lib/block_scout_web/views/address_view.ex:145
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
@ -1683,27 +1645,27 @@ msgstr ""
msgid "Market cap" msgid "Market cap"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:382 #: lib/block_scout_web/templates/transaction/overview.html.eex:405
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Max Fee per Gas" msgid "Max Fee per Gas"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:392 #: lib/block_scout_web/templates/transaction/overview.html.eex:415
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Max Priority Fee per Gas" msgid "Max Priority Fee per Gas"
msgstr "" msgstr ""
#: lib/block_scout_web/views/transaction_view.ex:317 #: lib/block_scout_web/views/transaction_view.ex:321
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Max of" msgid "Max of"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:372 #: lib/block_scout_web/templates/transaction/overview.html.eex:395
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Maximum gas amount approved for the transaction." msgid "Maximum gas amount approved for the transaction."
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:381 #: lib/block_scout_web/templates/transaction/overview.html.eex:404
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Maximum total amount per unit of gas a user is willing to pay for a transaction, including base fee and priority fee." msgid "Maximum total amount per unit of gas a user is willing to pay for a transaction, including base fee and priority fee."
msgstr "" msgstr ""
@ -1881,7 +1843,7 @@ msgid "No trace entries found."
msgstr "" msgstr ""
#: lib/block_scout_web/templates/block/overview.html.eex:196 #: lib/block_scout_web/templates/block/overview.html.eex:196
#: lib/block_scout_web/templates/transaction/overview.html.eex:436 #: lib/block_scout_web/templates/transaction/overview.html.eex:459
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Nonce" msgid "Nonce"
msgstr "" msgstr ""
@ -2001,8 +1963,8 @@ msgid "Parent Hash"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/layout/_topnav.html.eex:62 #: lib/block_scout_web/templates/layout/_topnav.html.eex:62
#: lib/block_scout_web/views/transaction_view.ex:346 #: lib/block_scout_web/views/transaction_view.ex:364
#: lib/block_scout_web/views/transaction_view.ex:384 #: lib/block_scout_web/views/transaction_view.ex:402
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Pending" msgid "Pending"
msgstr "" msgstr ""
@ -2028,7 +1990,7 @@ msgstr ""
msgid "Please select what types of notifications you will receive:" msgid "Please select what types of notifications you will receive:"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:438 #: lib/block_scout_web/templates/transaction/overview.html.eex:461
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Position" msgid "Position"
msgstr "" msgstr ""
@ -2038,11 +2000,6 @@ msgstr ""
msgid "Position %{index}" msgid "Position %{index}"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/_decoded_input.html.eex:18
#, elixir-autogen, elixir-format
msgid "Potential matches from contract method database:"
msgstr ""
#: lib/block_scout_web/templates/transaction/_decoded_input.html.eex:32 #: lib/block_scout_web/templates/transaction/_decoded_input.html.eex:32
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Potential matches from our contract method database:" msgid "Potential matches from our contract method database:"
@ -2054,7 +2011,7 @@ msgid "Press / and focus will be moved to the search field"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/chain/show.html.eex:41 #: lib/block_scout_web/templates/chain/show.html.eex:41
#: lib/block_scout_web/templates/layout/app.html.eex:47 #: lib/block_scout_web/templates/layout/app.html.eex:51
#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:95 #: lib/block_scout_web/templates/tokens/overview/_details.html.eex:95
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Price" msgid "Price"
@ -2065,13 +2022,13 @@ msgstr ""
msgid "Price per token on the exchanges" msgid "Price per token on the exchanges"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:352 #: lib/block_scout_web/templates/transaction/overview.html.eex:375
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Price per unit of gas specified by the sender. Higher gas prices can prioritize transaction inclusion during times of high usage." msgid "Price per unit of gas specified by the sender. Higher gas prices can prioritize transaction inclusion during times of high usage."
msgstr "" msgstr ""
#: lib/block_scout_web/templates/block/overview.html.eex:225 #: lib/block_scout_web/templates/block/overview.html.eex:225
#: lib/block_scout_web/templates/transaction/overview.html.eex:402 #: lib/block_scout_web/templates/transaction/overview.html.eex:425
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Priority Fee / Tip" msgid "Priority Fee / Tip"
msgstr "" msgstr ""
@ -2125,14 +2082,14 @@ msgstr ""
msgid "RPC" msgid "RPC"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:447 #: lib/block_scout_web/templates/transaction/overview.html.eex:470
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Raw Input" msgid "Raw Input"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/_tabs.html.eex:24 #: lib/block_scout_web/templates/transaction/_tabs.html.eex:24
#: lib/block_scout_web/templates/transaction_raw_trace/index.html.eex:7 #: lib/block_scout_web/templates/transaction_raw_trace/index.html.eex:7
#: lib/block_scout_web/views/transaction_view.ex:512 #: lib/block_scout_web/views/transaction_view.ex:530
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Raw Trace" msgid "Raw Trace"
msgstr "" msgstr ""
@ -2178,11 +2135,6 @@ msgstr ""
msgid "Request a public tag/label" msgid "Request a public tag/label"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/error422/index.html.eex:7
#, elixir-autogen, elixir-format
msgid "Request cannot be processed"
msgstr ""
#: lib/block_scout_web/templates/account/public_tags_request/index.html.eex:37 #: lib/block_scout_web/templates/account/public_tags_request/index.html.eex:37
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Request to add public tag" msgid "Request to add public tag"
@ -2322,21 +2274,11 @@ msgstr ""
msgid "Shows total assets held in the address" msgid "Shows total assets held in the address"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/layout/_account_menu_item.html.eex:29
#, elixir-autogen, elixir-format
msgid "Sign in"
msgstr ""
#: lib/block_scout_web/templates/layout/_account_menu_item.html.eex:20 #: lib/block_scout_web/templates/layout/_account_menu_item.html.eex:20
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Sign out" msgid "Sign out"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/layout/_account_menu_item.html.eex:11
#, elixir-autogen, elixir-format
msgid "Signed in as "
msgstr ""
#: lib/block_scout_web/templates/block/overview.html.eex:114 #: lib/block_scout_web/templates/block/overview.html.eex:114
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Size" msgid "Size"
@ -2400,11 +2342,6 @@ msgstr ""
msgid "Something went wrong, click to retry." msgid "Something went wrong, click to retry."
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/not_found.html.eex:6
#, elixir-autogen, elixir-format
msgid "Sorry, we are unable to locate this transaction hash"
msgstr ""
#: lib/block_scout_web/templates/address_contract_verification_via_multi_part_files/new.html.eex:63 #: lib/block_scout_web/templates/address_contract_verification_via_multi_part_files/new.html.eex:63
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Sources *.sol files" msgid "Sources *.sol files"
@ -2432,7 +2369,7 @@ msgstr ""
#: lib/block_scout_web/templates/transaction/_tabs.html.eex:29 #: lib/block_scout_web/templates/transaction/_tabs.html.eex:29
#: lib/block_scout_web/templates/transaction_state/index.html.eex:6 #: lib/block_scout_web/templates/transaction_state/index.html.eex:6
#: lib/block_scout_web/views/transaction_view.ex:513 #: lib/block_scout_web/views/transaction_view.ex:531
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "State changes" msgid "State changes"
msgstr "" msgstr ""
@ -2458,7 +2395,7 @@ msgid "Submit an Issue"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/_emission_reward_tile.html.eex:8 #: lib/block_scout_web/templates/transaction/_emission_reward_tile.html.eex:8
#: lib/block_scout_web/views/transaction_view.ex:348 #: lib/block_scout_web/views/transaction_view.ex:366
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Success" msgid "Success"
msgstr "" msgstr ""
@ -2694,11 +2631,6 @@ msgstr ""
msgid "This is useful to allow sending requests to blockscout without having to change anything about the request." msgid "This is useful to allow sending requests to blockscout without having to change anything about the request."
msgstr "" msgstr ""
#: lib/block_scout_web/templates/page_not_found/index.html.eex:8
#, elixir-autogen, elixir-format
msgid "This page is no longer explorable! If you are lost, use the search bar to find what you are looking for."
msgstr ""
#: lib/block_scout_web/templates/transaction_state/index.html.eex:17 #: lib/block_scout_web/templates/transaction_state/index.html.eex:17
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "This transaction hasn't changed state." msgid "This transaction hasn't changed state."
@ -2718,7 +2650,7 @@ msgstr ""
#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:32 #: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:32
#: lib/block_scout_web/templates/address_token_transfer/index.html.eex:34 #: lib/block_scout_web/templates/address_token_transfer/index.html.eex:34
#: lib/block_scout_web/templates/address_transaction/index.html.eex:28 #: lib/block_scout_web/templates/address_transaction/index.html.eex:28
#: lib/block_scout_web/templates/transaction/overview.html.eex:221 #: lib/block_scout_web/templates/transaction/overview.html.eex:244
#: lib/block_scout_web/views/address_internal_transaction_view.ex:9 #: lib/block_scout_web/views/address_internal_transaction_view.ex:9
#: lib/block_scout_web/views/address_token_transfer_view.ex:9 #: lib/block_scout_web/views/address_token_transfer_view.ex:9
#: lib/block_scout_web/views/address_transaction_view.ex:9 #: lib/block_scout_web/views/address_transaction_view.ex:9
@ -2749,13 +2681,13 @@ msgid "Token"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/common_components/_token_transfer_type_display_name.html.eex:3 #: lib/block_scout_web/templates/common_components/_token_transfer_type_display_name.html.eex:3
#: lib/block_scout_web/views/transaction_view.ex:446 #: lib/block_scout_web/views/transaction_view.ex:464
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Token Burning" msgid "Token Burning"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/common_components/_token_transfer_type_display_name.html.eex:7 #: lib/block_scout_web/templates/common_components/_token_transfer_type_display_name.html.eex:7
#: lib/block_scout_web/views/transaction_view.ex:447 #: lib/block_scout_web/views/transaction_view.ex:465
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Token Creation" msgid "Token Creation"
msgstr "" msgstr ""
@ -2783,14 +2715,14 @@ msgid "Token ID"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/common_components/_token_transfer_type_display_name.html.eex:5 #: lib/block_scout_web/templates/common_components/_token_transfer_type_display_name.html.eex:5
#: lib/block_scout_web/views/transaction_view.ex:445 #: lib/block_scout_web/views/transaction_view.ex:463
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Token Minting" msgid "Token Minting"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/common_components/_token_transfer_type_display_name.html.eex:9 #: lib/block_scout_web/templates/common_components/_token_transfer_type_display_name.html.eex:9
#: lib/block_scout_web/templates/common_components/_token_transfer_type_display_name.html.eex:11 #: lib/block_scout_web/templates/common_components/_token_transfer_type_display_name.html.eex:11
#: lib/block_scout_web/views/transaction_view.ex:448 #: lib/block_scout_web/views/transaction_view.ex:466
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Token Transfer" msgid "Token Transfer"
msgstr "" msgstr ""
@ -2806,7 +2738,7 @@ msgstr ""
#: lib/block_scout_web/views/address_view.ex:373 #: lib/block_scout_web/views/address_view.ex:373
#: lib/block_scout_web/views/tokens/instance/overview_view.ex:197 #: lib/block_scout_web/views/tokens/instance/overview_view.ex:197
#: lib/block_scout_web/views/tokens/overview_view.ex:39 #: lib/block_scout_web/views/tokens/overview_view.ex:39
#: lib/block_scout_web/views/transaction_view.ex:509 #: lib/block_scout_web/views/transaction_view.ex:527
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Token Transfers" msgid "Token Transfers"
msgstr "" msgstr ""
@ -2832,22 +2764,22 @@ msgstr ""
msgid "Tokens" msgid "Tokens"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:290 #: lib/block_scout_web/templates/transaction/overview.html.eex:313
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Tokens Burnt" msgid "Tokens Burnt"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:306 #: lib/block_scout_web/templates/transaction/overview.html.eex:329
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Tokens Created" msgid "Tokens Created"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:273 #: lib/block_scout_web/templates/transaction/overview.html.eex:296
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Tokens Minted" msgid "Tokens Minted"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:257 #: lib/block_scout_web/templates/transaction/overview.html.eex:280
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Tokens Transferred" msgid "Tokens Transferred"
msgstr "" msgstr ""
@ -2904,7 +2836,7 @@ msgstr ""
msgid "Total supply" msgid "Total supply"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:337 #: lib/block_scout_web/templates/transaction/overview.html.eex:360
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Total transaction fee." msgid "Total transaction fee."
msgstr "" msgstr ""
@ -2917,7 +2849,7 @@ msgstr ""
#: lib/block_scout_web/templates/account/tag_transaction/form.html.eex:11 #: lib/block_scout_web/templates/account/tag_transaction/form.html.eex:11
#: lib/block_scout_web/templates/account/tag_transaction/index.html.eex:23 #: lib/block_scout_web/templates/account/tag_transaction/index.html.eex:23
#: lib/block_scout_web/templates/address_logs/_logs.html.eex:19 #: lib/block_scout_web/templates/address_logs/_logs.html.eex:19
#: lib/block_scout_web/views/transaction_view.ex:458 #: lib/block_scout_web/views/transaction_view.ex:476
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Transaction" msgid "Transaction"
msgstr "" msgstr ""
@ -2932,7 +2864,7 @@ msgstr ""
msgid "Transaction %{transaction}, %{subnetwork} %{transaction}" msgid "Transaction %{transaction}, %{subnetwork} %{transaction}"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:412 #: lib/block_scout_web/templates/transaction/overview.html.eex:435
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Transaction Burnt Fee" msgid "Transaction Burnt Fee"
msgstr "" msgstr ""
@ -2942,7 +2874,7 @@ msgstr ""
msgid "Transaction Details" msgid "Transaction Details"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:338 #: lib/block_scout_web/templates/transaction/overview.html.eex:361
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Transaction Fee" msgid "Transaction Fee"
msgstr "" msgstr ""
@ -2965,17 +2897,17 @@ msgstr ""
msgid "Transaction Tags" msgid "Transaction Tags"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:362 #: lib/block_scout_web/templates/transaction/overview.html.eex:385
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Transaction Type" msgid "Transaction Type"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:435 #: lib/block_scout_web/templates/transaction/overview.html.eex:458
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Transaction number from the sending address. Each transaction sent from an address increments the nonce by 1." msgid "Transaction number from the sending address. Each transaction sent from an address increments the nonce by 1."
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:361 #: lib/block_scout_web/templates/transaction/overview.html.eex:384
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Transaction type, introduced in EIP-2718." msgid "Transaction type, introduced in EIP-2718."
msgstr "" msgstr ""
@ -3029,7 +2961,7 @@ msgstr ""
msgid "Twitter" msgid "Twitter"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/layout/app.html.eex:49 #: lib/block_scout_web/templates/layout/app.html.eex:53
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Tx/day" msgid "Tx/day"
msgstr "" msgstr ""
@ -3055,7 +2987,7 @@ msgstr ""
msgid "UML diagram" msgid "UML diagram"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:461 #: lib/block_scout_web/templates/transaction/overview.html.eex:484
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "UTF-8" msgid "UTF-8"
msgstr "" msgstr ""
@ -3071,7 +3003,7 @@ msgstr ""
msgid "Uncles" msgid "Uncles"
msgstr "" msgstr ""
#: lib/block_scout_web/views/transaction_view.ex:339 #: lib/block_scout_web/views/transaction_view.ex:357
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Unconfirmed" msgid "Unconfirmed"
msgstr "" msgstr ""
@ -3092,12 +3024,12 @@ msgstr ""
msgid "Update" msgid "Update"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:391 #: lib/block_scout_web/templates/transaction/overview.html.eex:414
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "User defined maximum fee (tip) per unit of gas paid to validator for transaction prioritization." msgid "User defined maximum fee (tip) per unit of gas paid to validator for transaction prioritization."
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:401 #: lib/block_scout_web/templates/transaction/overview.html.eex:424
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "User-defined tip sent to validator for transaction priority/inclusion." msgid "User-defined tip sent to validator for transaction priority/inclusion."
msgstr "" msgstr ""
@ -3132,12 +3064,12 @@ msgstr ""
msgid "Validator Name" msgid "Validator Name"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:323 #: lib/block_scout_web/templates/transaction/overview.html.eex:346
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Value" msgid "Value"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:322 #: lib/block_scout_web/templates/transaction/overview.html.eex:345
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Value sent in the native token (and USD) if applicable." msgid "Value sent in the native token (and USD) if applicable."
msgstr "" msgstr ""
@ -3399,11 +3331,6 @@ msgstr ""
msgid "Your name*" msgid "Your name*"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/error422/index.html.eex:8
#, elixir-autogen, elixir-format
msgid "Your request contained an error, perhaps a mistyped tx/block/address hash. Try again, and check the developer tools console for more info."
msgstr ""
#: lib/block_scout_web/templates/address/overview.html.eex:111 #: lib/block_scout_web/templates/address/overview.html.eex:111
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "at" msgid "at"
@ -3414,7 +3341,7 @@ msgstr ""
msgid "balance of the address" msgid "balance of the address"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:411 #: lib/block_scout_web/templates/transaction/overview.html.eex:434
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "burned for this transaction. Equals Block Base Fee per Gas * Gas Used." msgid "burned for this transaction. Equals Block Base Fee per Gas * Gas Used."
msgstr "" msgstr ""
@ -3429,7 +3356,7 @@ msgstr ""
msgid "button" msgid "button"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:230 #: lib/block_scout_web/templates/transaction/overview.html.eex:253
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "created" msgid "created"
msgstr "" msgstr ""
@ -3514,3 +3441,101 @@ msgstr ""
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "truffle flattener" msgid "truffle flattener"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/layout/_account_menu_item.html.eex:29
#, elixir-autogen, elixir-format
msgid "Sign in"
msgstr ""
#: lib/block_scout_web/templates/layout/_account_menu_item.html.eex:11
#, elixir-autogen, elixir-format
msgid "Signed in as "
msgstr ""
#: lib/block_scout_web/templates/transaction/not_found.html.eex:8
#, elixir-autogen, elixir-format
msgid "1. If you have just submitted this transaction please wait for at least 30 seconds before refreshing this page."
msgstr ""
#: lib/block_scout_web/templates/transaction/not_found.html.eex:9
#, elixir-autogen, elixir-format
msgid "2. It could still be in the TX Pool of a different node, waiting to be broadcasted."
msgstr ""
#: lib/block_scout_web/templates/transaction/not_found.html.eex:10
#, elixir-autogen, elixir-format
msgid "3. During times when the network is busy (i.e during ICOs) it can take a while for your transaction to propagate through the network and for us to index it."
msgstr ""
#: lib/block_scout_web/templates/transaction/not_found.html.eex:11
#, elixir-autogen, elixir-format
msgid "4. If it still does not show up after 1 hour, please check with your sender/exchange/wallet/transaction provider for additional information."
msgstr ""
#: lib/block_scout_web/templates/internal_server_error/index.html.eex:8
#, elixir-autogen, elixir-format
msgid "An unexpected error has occurred. Try reloading the page, or come back soon and try again."
msgstr ""
#: lib/block_scout_web/templates/error422/index.html.eex:9
#: lib/block_scout_web/templates/internal_server_error/index.html.eex:9
#: lib/block_scout_web/templates/page_not_found/index.html.eex:9
#: lib/block_scout_web/templates/transaction/not_found.html.eex:13
#, elixir-autogen, elixir-format
msgid "Back to home"
msgstr ""
#: lib/block_scout_web/templates/internal_server_error/index.html.eex:7
#, elixir-autogen, elixir-format
msgid "Internal server error"
msgstr ""
#: lib/block_scout_web/templates/error422/index.html.eex:7
#, elixir-autogen, elixir-format
msgid "Request cannot be processed"
msgstr ""
#: lib/block_scout_web/templates/transaction/not_found.html.eex:6
#, elixir-autogen, elixir-format
msgid "Sorry, we are unable to locate this transaction hash"
msgstr ""
#: lib/block_scout_web/templates/page_not_found/index.html.eex:8
#, elixir-autogen, elixir-format
msgid "This page is no longer explorable! If you are lost, use the search bar to find what you are looking for."
msgstr ""
#: lib/block_scout_web/templates/error422/index.html.eex:8
#, elixir-autogen, elixir-format
msgid "Your request contained an error, perhaps a mistyped tx/block/address hash. Try again, and check the developer tools console for more info."
msgstr ""
#: lib/block_scout_web/templates/transaction/_actions.html.eex:23
#, elixir-autogen, elixir-format
msgid "%{qty} of <span class=\"text-muted\">Token ID [%{link_to_id}]</span>"
msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:201
#, elixir-autogen, elixir-format
msgid "Highlighted events of the transaction."
msgstr ""
#: lib/block_scout_web/templates/transaction/_actions.html.eex:14
#, elixir-autogen, elixir-format
msgid "Mint of %{address} <span class=\"text-muted\">To</span> %{to}"
msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:203
#, elixir-autogen, elixir-format
msgid "Scroll to see more"
msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:202
#, elixir-autogen, elixir-format
msgid "Transaction Action"
msgstr ""
#: lib/block_scout_web/templates/transaction/_decoded_input.html.eex:18
#, elixir-autogen, elixir-format
msgid "Potential matches from contract method database:"
msgstr ""

@ -63,7 +63,7 @@ msgstr ""
msgid "%{subnetwork} Explorer - BlockScout" msgid "%{subnetwork} Explorer - BlockScout"
msgstr "" msgstr ""
#: lib/block_scout_web/views/transaction_view.ex:347 #: lib/block_scout_web/views/transaction_view.ex:365
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "(Awaiting internal transactions for status)" msgid "(Awaiting internal transactions for status)"
msgstr "" msgstr ""
@ -81,31 +81,11 @@ msgstr ""
msgid ") may be added for each contract. Click the Add Library button to add an additional one." msgid ") may be added for each contract. Click the Add Library button to add an additional one."
msgstr "" msgstr ""
#: lib/block_scout_web/templates/layout/app.html.eex:171 #: lib/block_scout_web/templates/layout/app.html.eex:175
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "- We're indexing this chain right now. Some of the counts may be inaccurate." msgid "- We're indexing this chain right now. Some of the counts may be inaccurate."
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/not_found.html.eex:8
#, elixir-autogen, elixir-format
msgid "1. If you have just submitted this transaction please wait for at least 30 seconds before refreshing this page."
msgstr ""
#: lib/block_scout_web/templates/transaction/not_found.html.eex:9
#, elixir-autogen, elixir-format
msgid "2. It could still be in the TX Pool of a different node, waiting to be broadcasted."
msgstr ""
#: lib/block_scout_web/templates/transaction/not_found.html.eex:10
#, elixir-autogen, elixir-format
msgid "3. During times when the network is busy (i.e during ICOs) it can take a while for your transaction to propagate through the network and for us to index it."
msgstr ""
#: lib/block_scout_web/templates/transaction/not_found.html.eex:11
#, elixir-autogen, elixir-format
msgid "4. If it still does not show up after 1 hour, please check with your sender/exchange/wallet/transaction provider for additional information."
msgstr ""
#: lib/block_scout_web/templates/block/overview.html.eex:195 #: lib/block_scout_web/templates/block/overview.html.eex:195
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "64-bit hash of value verifying proof-of-work (note: null for POA chains)." msgid "64-bit hash of value verifying proof-of-work (note: null for POA chains)."
@ -189,7 +169,7 @@ msgstr ""
msgid "Actions" msgid "Actions"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:425 #: lib/block_scout_web/templates/transaction/overview.html.eex:448
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Actual gas amount used by the transaction." msgid "Actual gas amount used by the transaction."
msgstr "" msgstr ""
@ -259,12 +239,12 @@ msgstr ""
msgid "Address" msgid "Address"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:217 #: lib/block_scout_web/templates/transaction/overview.html.eex:240
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Address (external or contract) receiving the transaction." msgid "Address (external or contract) receiving the transaction."
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:199 #: lib/block_scout_web/templates/transaction/overview.html.eex:222
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Address (external or contract) sending the transaction." msgid "Address (external or contract) sending the transaction."
msgstr "" msgstr ""
@ -329,7 +309,7 @@ msgstr ""
msgid "All tokens in the account and total value." msgid "All tokens in the account and total value."
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:411 #: lib/block_scout_web/templates/transaction/overview.html.eex:434
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Amount of" msgid "Amount of"
msgstr "" msgstr ""
@ -339,11 +319,6 @@ msgstr ""
msgid "Amount of distributed reward. Miners receive a static block reward + Tx fees + uncle fees." msgid "Amount of distributed reward. Miners receive a static block reward + Tx fees + uncle fees."
msgstr "" msgstr ""
#: lib/block_scout_web/templates/internal_server_error/index.html.eex:8
#, elixir-autogen, elixir-format
msgid "An unexpected error has occurred. Try reloading the page, or come back soon and try again."
msgstr ""
#: lib/block_scout_web/templates/api_docs/eth_rpc.html.eex:15 #: lib/block_scout_web/templates/api_docs/eth_rpc.html.eex:15
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Anything not in this list is not supported. Click on the method to be taken to the documentation for that method, and check the notes section for any potential differences." msgid "Anything not in this list is not supported. Click on the method to be taken to the documentation for that method, and check the notes section for any potential differences."
@ -389,14 +364,6 @@ msgstr ""
msgid "Back to Watch list (Cancel)" msgid "Back to Watch list (Cancel)"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/error422/index.html.eex:9
#: lib/block_scout_web/templates/internal_server_error/index.html.eex:9
#: lib/block_scout_web/templates/page_not_found/index.html.eex:9
#: lib/block_scout_web/templates/transaction/not_found.html.eex:13
#, elixir-autogen, elixir-format
msgid "Back to home"
msgstr ""
#: lib/block_scout_web/templates/account/watchlist/show.html.eex:24 #: lib/block_scout_web/templates/account/watchlist/show.html.eex:24
#: lib/block_scout_web/templates/address/overview.html.eex:150 #: lib/block_scout_web/templates/address/overview.html.eex:150
#: lib/block_scout_web/templates/address_token/overview.html.eex:51 #: lib/block_scout_web/templates/address_token/overview.html.eex:51
@ -431,7 +398,7 @@ msgstr ""
msgid "Base URL:" msgid "Base URL:"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:446 #: lib/block_scout_web/templates/transaction/overview.html.eex:469
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Binary data included with the transaction. See input / logs below for additional info." msgid "Binary data included with the transaction. See input / logs below for additional info."
msgstr "" msgstr ""
@ -465,7 +432,7 @@ msgstr ""
msgid "Block Height" msgid "Block Height"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/layout/app.html.eex:43 #: lib/block_scout_web/templates/layout/app.html.eex:47
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Block Mined, awaiting import..." msgid "Block Mined, awaiting import..."
msgstr "" msgstr ""
@ -512,7 +479,7 @@ msgstr ""
msgid "Blocks" msgid "Blocks"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/layout/app.html.eex:42 #: lib/block_scout_web/templates/layout/app.html.eex:46
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Blocks Indexed" msgid "Blocks Indexed"
msgstr "" msgstr ""
@ -525,7 +492,7 @@ msgstr ""
msgid "Blocks Validated" msgid "Blocks Validated"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/layout/app.html.eex:44 #: lib/block_scout_web/templates/layout/app.html.eex:48
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Blocks With Internal Transactions Indexed" msgid "Blocks With Internal Transactions Indexed"
msgstr "" msgstr ""
@ -657,7 +624,7 @@ msgstr ""
msgid "Compiler version" msgid "Compiler version"
msgstr "" msgstr ""
#: lib/block_scout_web/views/transaction_view.ex:340 #: lib/block_scout_web/views/transaction_view.ex:358
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Confirmed" msgid "Confirmed"
msgstr "" msgstr ""
@ -717,7 +684,7 @@ msgid "Constructor args"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:52 #: lib/block_scout_web/templates/tokens/overview/_details.html.eex:52
#: lib/block_scout_web/templates/transaction/overview.html.eex:227 #: lib/block_scout_web/templates/transaction/overview.html.eex:250
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Contract" msgid "Contract"
msgstr "" msgstr ""
@ -742,12 +709,12 @@ msgstr ""
msgid "Contract Address Pending" msgid "Contract Address Pending"
msgstr "" msgstr ""
#: lib/block_scout_web/views/transaction_view.ex:455 #: lib/block_scout_web/views/transaction_view.ex:473
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Contract Call" msgid "Contract Call"
msgstr "" msgstr ""
#: lib/block_scout_web/views/transaction_view.ex:452 #: lib/block_scout_web/views/transaction_view.ex:470
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Contract Creation" msgid "Contract Creation"
msgstr "" msgstr ""
@ -868,8 +835,8 @@ msgstr ""
#: lib/block_scout_web/templates/account/watchlist_address/row.html.eex:7 #: lib/block_scout_web/templates/account/watchlist_address/row.html.eex:7
#: lib/block_scout_web/templates/transaction/_total_transfers_from_to.html.eex:17 #: lib/block_scout_web/templates/transaction/_total_transfers_from_to.html.eex:17
#: lib/block_scout_web/templates/transaction/_total_transfers_from_to.html.eex:18 #: lib/block_scout_web/templates/transaction/_total_transfers_from_to.html.eex:18
#: lib/block_scout_web/templates/transaction/overview.html.eex:207 #: lib/block_scout_web/templates/transaction/overview.html.eex:230
#: lib/block_scout_web/templates/transaction/overview.html.eex:208 #: lib/block_scout_web/templates/transaction/overview.html.eex:231
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Copy From Address" msgid "Copy From Address"
msgstr "" msgstr ""
@ -904,10 +871,10 @@ msgstr ""
#: lib/block_scout_web/templates/transaction/_total_transfers_from_to.html.eex:34 #: lib/block_scout_web/templates/transaction/_total_transfers_from_to.html.eex:34
#: lib/block_scout_web/templates/transaction/_total_transfers_from_to.html.eex:35 #: lib/block_scout_web/templates/transaction/_total_transfers_from_to.html.eex:35
#: lib/block_scout_web/templates/transaction/overview.html.eex:234 #: lib/block_scout_web/templates/transaction/overview.html.eex:257
#: lib/block_scout_web/templates/transaction/overview.html.eex:235 #: lib/block_scout_web/templates/transaction/overview.html.eex:258
#: lib/block_scout_web/templates/transaction/overview.html.eex:242 #: lib/block_scout_web/templates/transaction/overview.html.eex:265
#: lib/block_scout_web/templates/transaction/overview.html.eex:243 #: lib/block_scout_web/templates/transaction/overview.html.eex:266
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Copy To Address" msgid "Copy To Address"
msgstr "" msgstr ""
@ -928,20 +895,20 @@ msgstr ""
msgid "Copy Txn Hash" msgid "Copy Txn Hash"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:472 #: lib/block_scout_web/templates/transaction/overview.html.eex:495
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Copy Txn Hex Input" msgid "Copy Txn Hex Input"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:478 #: lib/block_scout_web/templates/transaction/overview.html.eex:501
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Copy Txn UTF-8 Input" msgid "Copy Txn UTF-8 Input"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/log/_data_decoded_view.html.eex:20 #: lib/block_scout_web/templates/log/_data_decoded_view.html.eex:20
#: lib/block_scout_web/templates/transaction/_decoded_input_body.html.eex:41 #: lib/block_scout_web/templates/transaction/_decoded_input_body.html.eex:41
#: lib/block_scout_web/templates/transaction/overview.html.eex:471 #: lib/block_scout_web/templates/transaction/overview.html.eex:494
#: lib/block_scout_web/templates/transaction/overview.html.eex:477 #: lib/block_scout_web/templates/transaction/overview.html.eex:500
#: lib/block_scout_web/templates/transaction_raw_trace/index.html.eex:14 #: lib/block_scout_web/templates/transaction_raw_trace/index.html.eex:14
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Copy Value" msgid "Copy Value"
@ -1144,12 +1111,12 @@ msgstr ""
msgid "EIP-1167" msgid "EIP-1167"
msgstr "" msgstr ""
#: lib/block_scout_web/views/transaction_view.ex:212 #: lib/block_scout_web/views/transaction_view.ex:216
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "ERC-1155 " msgid "ERC-1155 "
msgstr "" msgstr ""
#: lib/block_scout_web/views/transaction_view.ex:210 #: lib/block_scout_web/views/transaction_view.ex:214
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "ERC-20 " msgid "ERC-20 "
msgstr "" msgstr ""
@ -1159,7 +1126,7 @@ msgstr ""
msgid "ERC-20 tokens (beta)" msgid "ERC-20 tokens (beta)"
msgstr "" msgstr ""
#: lib/block_scout_web/views/transaction_view.ex:211 #: lib/block_scout_web/views/transaction_view.ex:215
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "ERC-721 " msgid "ERC-721 "
msgstr "" msgstr ""
@ -1250,12 +1217,12 @@ msgstr ""
msgid "Error trying to fetch balances." msgid "Error trying to fetch balances."
msgstr "" msgstr ""
#: lib/block_scout_web/views/transaction_view.ex:351 #: lib/block_scout_web/views/transaction_view.ex:369
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Error: %{reason}" msgid "Error: %{reason}"
msgstr "" msgstr ""
#: lib/block_scout_web/views/transaction_view.ex:349 #: lib/block_scout_web/views/transaction_view.ex:367
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Error: (Awaiting internal transactions for reason)" msgid "Error: (Awaiting internal transactions for reason)"
msgstr "" msgstr ""
@ -1369,7 +1336,7 @@ msgstr ""
#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:38 #: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:38
#: lib/block_scout_web/templates/address_token_transfer/index.html.eex:40 #: lib/block_scout_web/templates/address_token_transfer/index.html.eex:40
#: lib/block_scout_web/templates/address_transaction/index.html.eex:34 #: lib/block_scout_web/templates/address_transaction/index.html.eex:34
#: lib/block_scout_web/templates/transaction/overview.html.eex:200 #: lib/block_scout_web/templates/transaction/overview.html.eex:223
#: lib/block_scout_web/views/address_internal_transaction_view.ex:10 #: lib/block_scout_web/views/address_internal_transaction_view.ex:10
#: lib/block_scout_web/views/address_token_transfer_view.ex:10 #: lib/block_scout_web/views/address_token_transfer_view.ex:10
#: lib/block_scout_web/views/address_transaction_view.ex:10 #: lib/block_scout_web/views/address_transaction_view.ex:10
@ -1384,12 +1351,12 @@ msgstr ""
#: lib/block_scout_web/templates/block/_tile.html.eex:67 #: lib/block_scout_web/templates/block/_tile.html.eex:67
#: lib/block_scout_web/templates/block/overview.html.eex:187 #: lib/block_scout_web/templates/block/overview.html.eex:187
#: lib/block_scout_web/templates/transaction/overview.html.eex:373 #: lib/block_scout_web/templates/transaction/overview.html.eex:396
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Gas Limit" msgid "Gas Limit"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:353 #: lib/block_scout_web/templates/transaction/overview.html.eex:376
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Gas Price" msgid "Gas Price"
msgstr "" msgstr ""
@ -1401,7 +1368,7 @@ msgstr ""
msgid "Gas Used" msgid "Gas Used"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:426 #: lib/block_scout_web/templates/transaction/overview.html.eex:449
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Gas Used by Transaction" msgid "Gas Used by Transaction"
msgstr "" msgstr ""
@ -1453,8 +1420,8 @@ msgstr ""
msgid "Hash" msgid "Hash"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:454 #: lib/block_scout_web/templates/transaction/overview.html.eex:477
#: lib/block_scout_web/templates/transaction/overview.html.eex:458 #: lib/block_scout_web/templates/transaction/overview.html.eex:481
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Hex (Default)" msgid "Hex (Default)"
msgstr "" msgstr ""
@ -1508,7 +1475,7 @@ msgstr ""
msgid "Incoming" msgid "Incoming"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:438 #: lib/block_scout_web/templates/transaction/overview.html.eex:461
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Index position of Transaction in the block." msgid "Index position of Transaction in the block."
msgstr "" msgstr ""
@ -1528,7 +1495,7 @@ msgstr ""
msgid "Input" msgid "Input"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:219 #: lib/block_scout_web/templates/transaction/overview.html.eex:242
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Interacted With (To)" msgid "Interacted With (To)"
msgstr "" msgstr ""
@ -1543,16 +1510,11 @@ msgstr ""
#: lib/block_scout_web/templates/transaction/_tabs.html.eex:11 #: lib/block_scout_web/templates/transaction/_tabs.html.eex:11
#: lib/block_scout_web/templates/transaction_internal_transaction/index.html.eex:6 #: lib/block_scout_web/templates/transaction_internal_transaction/index.html.eex:6
#: lib/block_scout_web/views/address_view.ex:371 #: lib/block_scout_web/views/address_view.ex:371
#: lib/block_scout_web/views/transaction_view.ex:510 #: lib/block_scout_web/views/transaction_view.ex:528
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Internal Transactions" msgid "Internal Transactions"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/internal_server_error/index.html.eex:7
#, elixir-autogen, elixir-format
msgid "Internal server error"
msgstr ""
#: lib/block_scout_web/templates/tokens/inventory/index.html.eex:16 #: lib/block_scout_web/templates/tokens/inventory/index.html.eex:16
#: lib/block_scout_web/templates/tokens/overview/_tabs.html.eex:19 #: lib/block_scout_web/templates/tokens/overview/_tabs.html.eex:19
#: lib/block_scout_web/views/tokens/overview_view.ex:42 #: lib/block_scout_web/views/tokens/overview_view.ex:42
@ -1582,7 +1544,7 @@ msgstr ""
msgid "Learn more" msgid "Learn more"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/layout/app.html.eex:45 #: lib/block_scout_web/templates/layout/app.html.eex:49
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Less than" msgid "Less than"
msgstr "" msgstr ""
@ -1603,22 +1565,22 @@ msgstr ""
msgid "License ID" msgid "License ID"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:305 #: lib/block_scout_web/templates/transaction/overview.html.eex:328
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "List of ERC-1155 tokens created in the transaction." msgid "List of ERC-1155 tokens created in the transaction."
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:289 #: lib/block_scout_web/templates/transaction/overview.html.eex:312
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "List of token burnt in the transaction." msgid "List of token burnt in the transaction."
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:272 #: lib/block_scout_web/templates/transaction/overview.html.eex:295
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "List of token minted in the transaction." msgid "List of token minted in the transaction."
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:256 #: lib/block_scout_web/templates/transaction/overview.html.eex:279
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "List of token transferred in the transaction." msgid "List of token transferred in the transaction."
msgstr "" msgstr ""
@ -1660,7 +1622,7 @@ msgstr ""
#: lib/block_scout_web/templates/transaction/_tabs.html.eex:17 #: lib/block_scout_web/templates/transaction/_tabs.html.eex:17
#: lib/block_scout_web/templates/transaction_log/index.html.eex:8 #: lib/block_scout_web/templates/transaction_log/index.html.eex:8
#: lib/block_scout_web/views/address_view.ex:382 #: lib/block_scout_web/views/address_view.ex:382
#: lib/block_scout_web/views/transaction_view.ex:511 #: lib/block_scout_web/views/transaction_view.ex:529
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Logs" msgid "Logs"
msgstr "" msgstr ""
@ -1671,7 +1633,7 @@ msgid "Main Networks"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/chain/show.html.eex:52 #: lib/block_scout_web/templates/chain/show.html.eex:52
#: lib/block_scout_web/templates/layout/app.html.eex:46 #: lib/block_scout_web/templates/layout/app.html.eex:50
#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:84 #: lib/block_scout_web/templates/tokens/overview/_details.html.eex:84
#: lib/block_scout_web/views/address_view.ex:145 #: lib/block_scout_web/views/address_view.ex:145
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
@ -1683,27 +1645,27 @@ msgstr ""
msgid "Market cap" msgid "Market cap"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:382 #: lib/block_scout_web/templates/transaction/overview.html.eex:405
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Max Fee per Gas" msgid "Max Fee per Gas"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:392 #: lib/block_scout_web/templates/transaction/overview.html.eex:415
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Max Priority Fee per Gas" msgid "Max Priority Fee per Gas"
msgstr "" msgstr ""
#: lib/block_scout_web/views/transaction_view.ex:317 #: lib/block_scout_web/views/transaction_view.ex:321
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Max of" msgid "Max of"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:372 #: lib/block_scout_web/templates/transaction/overview.html.eex:395
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Maximum gas amount approved for the transaction." msgid "Maximum gas amount approved for the transaction."
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:381 #: lib/block_scout_web/templates/transaction/overview.html.eex:404
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Maximum total amount per unit of gas a user is willing to pay for a transaction, including base fee and priority fee." msgid "Maximum total amount per unit of gas a user is willing to pay for a transaction, including base fee and priority fee."
msgstr "" msgstr ""
@ -1881,7 +1843,7 @@ msgid "No trace entries found."
msgstr "" msgstr ""
#: lib/block_scout_web/templates/block/overview.html.eex:196 #: lib/block_scout_web/templates/block/overview.html.eex:196
#: lib/block_scout_web/templates/transaction/overview.html.eex:436 #: lib/block_scout_web/templates/transaction/overview.html.eex:459
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Nonce" msgid "Nonce"
msgstr "" msgstr ""
@ -2001,8 +1963,8 @@ msgid "Parent Hash"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/layout/_topnav.html.eex:62 #: lib/block_scout_web/templates/layout/_topnav.html.eex:62
#: lib/block_scout_web/views/transaction_view.ex:346 #: lib/block_scout_web/views/transaction_view.ex:364
#: lib/block_scout_web/views/transaction_view.ex:384 #: lib/block_scout_web/views/transaction_view.ex:402
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Pending" msgid "Pending"
msgstr "" msgstr ""
@ -2028,7 +1990,7 @@ msgstr ""
msgid "Please select what types of notifications you will receive:" msgid "Please select what types of notifications you will receive:"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:438 #: lib/block_scout_web/templates/transaction/overview.html.eex:461
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Position" msgid "Position"
msgstr "" msgstr ""
@ -2038,11 +2000,6 @@ msgstr ""
msgid "Position %{index}" msgid "Position %{index}"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/_decoded_input.html.eex:18
#, elixir-autogen, elixir-format
msgid "Potential matches from contract method database:"
msgstr ""
#: lib/block_scout_web/templates/transaction/_decoded_input.html.eex:32 #: lib/block_scout_web/templates/transaction/_decoded_input.html.eex:32
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Potential matches from our contract method database:" msgid "Potential matches from our contract method database:"
@ -2054,7 +2011,7 @@ msgid "Press / and focus will be moved to the search field"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/chain/show.html.eex:41 #: lib/block_scout_web/templates/chain/show.html.eex:41
#: lib/block_scout_web/templates/layout/app.html.eex:47 #: lib/block_scout_web/templates/layout/app.html.eex:51
#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:95 #: lib/block_scout_web/templates/tokens/overview/_details.html.eex:95
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Price" msgid "Price"
@ -2065,13 +2022,13 @@ msgstr ""
msgid "Price per token on the exchanges" msgid "Price per token on the exchanges"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:352 #: lib/block_scout_web/templates/transaction/overview.html.eex:375
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Price per unit of gas specified by the sender. Higher gas prices can prioritize transaction inclusion during times of high usage." msgid "Price per unit of gas specified by the sender. Higher gas prices can prioritize transaction inclusion during times of high usage."
msgstr "" msgstr ""
#: lib/block_scout_web/templates/block/overview.html.eex:225 #: lib/block_scout_web/templates/block/overview.html.eex:225
#: lib/block_scout_web/templates/transaction/overview.html.eex:402 #: lib/block_scout_web/templates/transaction/overview.html.eex:425
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Priority Fee / Tip" msgid "Priority Fee / Tip"
msgstr "" msgstr ""
@ -2125,14 +2082,14 @@ msgstr ""
msgid "RPC" msgid "RPC"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:447 #: lib/block_scout_web/templates/transaction/overview.html.eex:470
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Raw Input" msgid "Raw Input"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/_tabs.html.eex:24 #: lib/block_scout_web/templates/transaction/_tabs.html.eex:24
#: lib/block_scout_web/templates/transaction_raw_trace/index.html.eex:7 #: lib/block_scout_web/templates/transaction_raw_trace/index.html.eex:7
#: lib/block_scout_web/views/transaction_view.ex:512 #: lib/block_scout_web/views/transaction_view.ex:530
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Raw Trace" msgid "Raw Trace"
msgstr "" msgstr ""
@ -2178,11 +2135,6 @@ msgstr ""
msgid "Request a public tag/label" msgid "Request a public tag/label"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/error422/index.html.eex:7
#, elixir-autogen, elixir-format
msgid "Request cannot be processed"
msgstr ""
#: lib/block_scout_web/templates/account/public_tags_request/index.html.eex:37 #: lib/block_scout_web/templates/account/public_tags_request/index.html.eex:37
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Request to add public tag" msgid "Request to add public tag"
@ -2322,21 +2274,11 @@ msgstr ""
msgid "Shows total assets held in the address" msgid "Shows total assets held in the address"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/layout/_account_menu_item.html.eex:29
#, elixir-autogen, elixir-format
msgid "Sign in"
msgstr ""
#: lib/block_scout_web/templates/layout/_account_menu_item.html.eex:20 #: lib/block_scout_web/templates/layout/_account_menu_item.html.eex:20
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Sign out" msgid "Sign out"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/layout/_account_menu_item.html.eex:11
#, elixir-autogen, elixir-format
msgid "Signed in as "
msgstr ""
#: lib/block_scout_web/templates/block/overview.html.eex:114 #: lib/block_scout_web/templates/block/overview.html.eex:114
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Size" msgid "Size"
@ -2400,11 +2342,6 @@ msgstr ""
msgid "Something went wrong, click to retry." msgid "Something went wrong, click to retry."
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/not_found.html.eex:6
#, elixir-autogen, elixir-format
msgid "Sorry, we are unable to locate this transaction hash"
msgstr ""
#: lib/block_scout_web/templates/address_contract_verification_via_multi_part_files/new.html.eex:63 #: lib/block_scout_web/templates/address_contract_verification_via_multi_part_files/new.html.eex:63
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Sources *.sol files" msgid "Sources *.sol files"
@ -2432,7 +2369,7 @@ msgstr ""
#: lib/block_scout_web/templates/transaction/_tabs.html.eex:29 #: lib/block_scout_web/templates/transaction/_tabs.html.eex:29
#: lib/block_scout_web/templates/transaction_state/index.html.eex:6 #: lib/block_scout_web/templates/transaction_state/index.html.eex:6
#: lib/block_scout_web/views/transaction_view.ex:513 #: lib/block_scout_web/views/transaction_view.ex:531
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "State changes" msgid "State changes"
msgstr "" msgstr ""
@ -2458,7 +2395,7 @@ msgid "Submit an Issue"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/_emission_reward_tile.html.eex:8 #: lib/block_scout_web/templates/transaction/_emission_reward_tile.html.eex:8
#: lib/block_scout_web/views/transaction_view.ex:348 #: lib/block_scout_web/views/transaction_view.ex:366
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Success" msgid "Success"
msgstr "" msgstr ""
@ -2694,11 +2631,6 @@ msgstr ""
msgid "This is useful to allow sending requests to blockscout without having to change anything about the request." msgid "This is useful to allow sending requests to blockscout without having to change anything about the request."
msgstr "" msgstr ""
#: lib/block_scout_web/templates/page_not_found/index.html.eex:8
#, elixir-autogen, elixir-format
msgid "This page is no longer explorable! If you are lost, use the search bar to find what you are looking for."
msgstr ""
#: lib/block_scout_web/templates/transaction_state/index.html.eex:17 #: lib/block_scout_web/templates/transaction_state/index.html.eex:17
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "This transaction hasn't changed state." msgid "This transaction hasn't changed state."
@ -2718,7 +2650,7 @@ msgstr ""
#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:32 #: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:32
#: lib/block_scout_web/templates/address_token_transfer/index.html.eex:34 #: lib/block_scout_web/templates/address_token_transfer/index.html.eex:34
#: lib/block_scout_web/templates/address_transaction/index.html.eex:28 #: lib/block_scout_web/templates/address_transaction/index.html.eex:28
#: lib/block_scout_web/templates/transaction/overview.html.eex:221 #: lib/block_scout_web/templates/transaction/overview.html.eex:244
#: lib/block_scout_web/views/address_internal_transaction_view.ex:9 #: lib/block_scout_web/views/address_internal_transaction_view.ex:9
#: lib/block_scout_web/views/address_token_transfer_view.ex:9 #: lib/block_scout_web/views/address_token_transfer_view.ex:9
#: lib/block_scout_web/views/address_transaction_view.ex:9 #: lib/block_scout_web/views/address_transaction_view.ex:9
@ -2749,13 +2681,13 @@ msgid "Token"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/common_components/_token_transfer_type_display_name.html.eex:3 #: lib/block_scout_web/templates/common_components/_token_transfer_type_display_name.html.eex:3
#: lib/block_scout_web/views/transaction_view.ex:446 #: lib/block_scout_web/views/transaction_view.ex:464
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Token Burning" msgid "Token Burning"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/common_components/_token_transfer_type_display_name.html.eex:7 #: lib/block_scout_web/templates/common_components/_token_transfer_type_display_name.html.eex:7
#: lib/block_scout_web/views/transaction_view.ex:447 #: lib/block_scout_web/views/transaction_view.ex:465
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Token Creation" msgid "Token Creation"
msgstr "" msgstr ""
@ -2783,14 +2715,14 @@ msgid "Token ID"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/common_components/_token_transfer_type_display_name.html.eex:5 #: lib/block_scout_web/templates/common_components/_token_transfer_type_display_name.html.eex:5
#: lib/block_scout_web/views/transaction_view.ex:445 #: lib/block_scout_web/views/transaction_view.ex:463
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Token Minting" msgid "Token Minting"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/common_components/_token_transfer_type_display_name.html.eex:9 #: lib/block_scout_web/templates/common_components/_token_transfer_type_display_name.html.eex:9
#: lib/block_scout_web/templates/common_components/_token_transfer_type_display_name.html.eex:11 #: lib/block_scout_web/templates/common_components/_token_transfer_type_display_name.html.eex:11
#: lib/block_scout_web/views/transaction_view.ex:448 #: lib/block_scout_web/views/transaction_view.ex:466
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Token Transfer" msgid "Token Transfer"
msgstr "" msgstr ""
@ -2806,7 +2738,7 @@ msgstr ""
#: lib/block_scout_web/views/address_view.ex:373 #: lib/block_scout_web/views/address_view.ex:373
#: lib/block_scout_web/views/tokens/instance/overview_view.ex:197 #: lib/block_scout_web/views/tokens/instance/overview_view.ex:197
#: lib/block_scout_web/views/tokens/overview_view.ex:39 #: lib/block_scout_web/views/tokens/overview_view.ex:39
#: lib/block_scout_web/views/transaction_view.ex:509 #: lib/block_scout_web/views/transaction_view.ex:527
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Token Transfers" msgid "Token Transfers"
msgstr "" msgstr ""
@ -2832,22 +2764,22 @@ msgstr ""
msgid "Tokens" msgid "Tokens"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:290 #: lib/block_scout_web/templates/transaction/overview.html.eex:313
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Tokens Burnt" msgid "Tokens Burnt"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:306 #: lib/block_scout_web/templates/transaction/overview.html.eex:329
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Tokens Created" msgid "Tokens Created"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:273 #: lib/block_scout_web/templates/transaction/overview.html.eex:296
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Tokens Minted" msgid "Tokens Minted"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:257 #: lib/block_scout_web/templates/transaction/overview.html.eex:280
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Tokens Transferred" msgid "Tokens Transferred"
msgstr "" msgstr ""
@ -2904,7 +2836,7 @@ msgstr ""
msgid "Total supply" msgid "Total supply"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:337 #: lib/block_scout_web/templates/transaction/overview.html.eex:360
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Total transaction fee." msgid "Total transaction fee."
msgstr "" msgstr ""
@ -2917,7 +2849,7 @@ msgstr ""
#: lib/block_scout_web/templates/account/tag_transaction/form.html.eex:11 #: lib/block_scout_web/templates/account/tag_transaction/form.html.eex:11
#: lib/block_scout_web/templates/account/tag_transaction/index.html.eex:23 #: lib/block_scout_web/templates/account/tag_transaction/index.html.eex:23
#: lib/block_scout_web/templates/address_logs/_logs.html.eex:19 #: lib/block_scout_web/templates/address_logs/_logs.html.eex:19
#: lib/block_scout_web/views/transaction_view.ex:458 #: lib/block_scout_web/views/transaction_view.ex:476
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Transaction" msgid "Transaction"
msgstr "" msgstr ""
@ -2932,7 +2864,7 @@ msgstr ""
msgid "Transaction %{transaction}, %{subnetwork} %{transaction}" msgid "Transaction %{transaction}, %{subnetwork} %{transaction}"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:412 #: lib/block_scout_web/templates/transaction/overview.html.eex:435
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Transaction Burnt Fee" msgid "Transaction Burnt Fee"
msgstr "" msgstr ""
@ -2942,7 +2874,7 @@ msgstr ""
msgid "Transaction Details" msgid "Transaction Details"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:338 #: lib/block_scout_web/templates/transaction/overview.html.eex:361
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Transaction Fee" msgid "Transaction Fee"
msgstr "" msgstr ""
@ -2965,17 +2897,17 @@ msgstr ""
msgid "Transaction Tags" msgid "Transaction Tags"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:362 #: lib/block_scout_web/templates/transaction/overview.html.eex:385
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Transaction Type" msgid "Transaction Type"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:435 #: lib/block_scout_web/templates/transaction/overview.html.eex:458
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Transaction number from the sending address. Each transaction sent from an address increments the nonce by 1." msgid "Transaction number from the sending address. Each transaction sent from an address increments the nonce by 1."
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:361 #: lib/block_scout_web/templates/transaction/overview.html.eex:384
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Transaction type, introduced in EIP-2718." msgid "Transaction type, introduced in EIP-2718."
msgstr "" msgstr ""
@ -3029,7 +2961,7 @@ msgstr ""
msgid "Twitter" msgid "Twitter"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/layout/app.html.eex:49 #: lib/block_scout_web/templates/layout/app.html.eex:53
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Tx/day" msgid "Tx/day"
msgstr "" msgstr ""
@ -3055,7 +2987,7 @@ msgstr ""
msgid "UML diagram" msgid "UML diagram"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:461 #: lib/block_scout_web/templates/transaction/overview.html.eex:484
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "UTF-8" msgid "UTF-8"
msgstr "" msgstr ""
@ -3071,7 +3003,7 @@ msgstr ""
msgid "Uncles" msgid "Uncles"
msgstr "" msgstr ""
#: lib/block_scout_web/views/transaction_view.ex:339 #: lib/block_scout_web/views/transaction_view.ex:357
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Unconfirmed" msgid "Unconfirmed"
msgstr "" msgstr ""
@ -3092,12 +3024,12 @@ msgstr ""
msgid "Update" msgid "Update"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:391 #: lib/block_scout_web/templates/transaction/overview.html.eex:414
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "User defined maximum fee (tip) per unit of gas paid to validator for transaction prioritization." msgid "User defined maximum fee (tip) per unit of gas paid to validator for transaction prioritization."
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:401 #: lib/block_scout_web/templates/transaction/overview.html.eex:424
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "User-defined tip sent to validator for transaction priority/inclusion." msgid "User-defined tip sent to validator for transaction priority/inclusion."
msgstr "" msgstr ""
@ -3132,12 +3064,12 @@ msgstr ""
msgid "Validator Name" msgid "Validator Name"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:323 #: lib/block_scout_web/templates/transaction/overview.html.eex:346
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Value" msgid "Value"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:322 #: lib/block_scout_web/templates/transaction/overview.html.eex:345
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Value sent in the native token (and USD) if applicable." msgid "Value sent in the native token (and USD) if applicable."
msgstr "" msgstr ""
@ -3399,11 +3331,6 @@ msgstr ""
msgid "Your name*" msgid "Your name*"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/error422/index.html.eex:8
#, elixir-autogen, elixir-format
msgid "Your request contained an error, perhaps a mistyped tx/block/address hash. Try again, and check the developer tools console for more info."
msgstr ""
#: lib/block_scout_web/templates/address/overview.html.eex:111 #: lib/block_scout_web/templates/address/overview.html.eex:111
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "at" msgid "at"
@ -3414,7 +3341,7 @@ msgstr ""
msgid "balance of the address" msgid "balance of the address"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:411 #: lib/block_scout_web/templates/transaction/overview.html.eex:434
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "burned for this transaction. Equals Block Base Fee per Gas * Gas Used." msgid "burned for this transaction. Equals Block Base Fee per Gas * Gas Used."
msgstr "" msgstr ""
@ -3429,7 +3356,7 @@ msgstr ""
msgid "button" msgid "button"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:230 #: lib/block_scout_web/templates/transaction/overview.html.eex:253
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "created" msgid "created"
msgstr "" msgstr ""
@ -3514,3 +3441,101 @@ msgstr ""
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "truffle flattener" msgid "truffle flattener"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/layout/_account_menu_item.html.eex:29
#, elixir-autogen, elixir-format
msgid "Sign in"
msgstr ""
#: lib/block_scout_web/templates/layout/_account_menu_item.html.eex:11
#, elixir-autogen, elixir-format
msgid "Signed in as "
msgstr ""
#: lib/block_scout_web/templates/transaction/not_found.html.eex:8
#, elixir-autogen, elixir-format, fuzzy
msgid "1. If you have just submitted this transaction please wait for at least 30 seconds before refreshing this page."
msgstr ""
#: lib/block_scout_web/templates/transaction/not_found.html.eex:9
#, elixir-autogen, elixir-format, fuzzy
msgid "2. It could still be in the TX Pool of a different node, waiting to be broadcasted."
msgstr ""
#: lib/block_scout_web/templates/transaction/not_found.html.eex:10
#, elixir-autogen, elixir-format, fuzzy
msgid "3. During times when the network is busy (i.e during ICOs) it can take a while for your transaction to propagate through the network and for us to index it."
msgstr ""
#: lib/block_scout_web/templates/transaction/not_found.html.eex:11
#, elixir-autogen, elixir-format, fuzzy
msgid "4. If it still does not show up after 1 hour, please check with your sender/exchange/wallet/transaction provider for additional information."
msgstr ""
#: lib/block_scout_web/templates/internal_server_error/index.html.eex:8
#, elixir-autogen, elixir-format
msgid "An unexpected error has occurred. Try reloading the page, or come back soon and try again."
msgstr ""
#: lib/block_scout_web/templates/error422/index.html.eex:9
#: lib/block_scout_web/templates/internal_server_error/index.html.eex:9
#: lib/block_scout_web/templates/page_not_found/index.html.eex:9
#: lib/block_scout_web/templates/transaction/not_found.html.eex:13
#, elixir-autogen, elixir-format, fuzzy
msgid "Back to home"
msgstr ""
#: lib/block_scout_web/templates/internal_server_error/index.html.eex:7
#, elixir-autogen, elixir-format
msgid "Internal server error"
msgstr ""
#: lib/block_scout_web/templates/error422/index.html.eex:7
#, elixir-autogen, elixir-format
msgid "Request cannot be processed"
msgstr ""
#: lib/block_scout_web/templates/transaction/not_found.html.eex:6
#, elixir-autogen, elixir-format, fuzzy
msgid "Sorry, we are unable to locate this transaction hash"
msgstr ""
#: lib/block_scout_web/templates/page_not_found/index.html.eex:8
#, elixir-autogen, elixir-format
msgid "This page is no longer explorable! If you are lost, use the search bar to find what you are looking for."
msgstr ""
#: lib/block_scout_web/templates/error422/index.html.eex:8
#, elixir-autogen, elixir-format
msgid "Your request contained an error, perhaps a mistyped tx/block/address hash. Try again, and check the developer tools console for more info."
msgstr ""
#: lib/block_scout_web/templates/transaction/_actions.html.eex:23
#, elixir-autogen, elixir-format
msgid "%{qty} of <span class=\"text-muted\">Token ID [%{link_to_id}]</span>"
msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:201
#, elixir-autogen, elixir-format
msgid "Highlighted events of the transaction."
msgstr ""
#: lib/block_scout_web/templates/transaction/_actions.html.eex:14
#, elixir-autogen, elixir-format
msgid "Mint of %{address} <span class=\"text-muted\">To</span> %{to}"
msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:203
#, elixir-autogen, elixir-format
msgid "Scroll to see more"
msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:202
#, elixir-autogen, elixir-format, fuzzy
msgid "Transaction Action"
msgstr ""
#: lib/block_scout_web/templates/transaction/_decoded_input.html.eex:18
#, elixir-autogen, elixir-format, fuzzy
msgid "Potential matches from contract method database:"
msgstr ""

@ -0,0 +1,75 @@
defmodule Explorer.Chain.Import.Runner.TransactionActions do
@moduledoc """
Bulk imports `t:Explorer.Chain.TransactionAction.t/0`.
"""
require Ecto.Query
alias Ecto.{Changeset, Multi, Repo}
alias Explorer.Chain.{Import, TransactionAction}
alias Explorer.Prometheus.Instrumenter
@behaviour Import.Runner
# milliseconds
@timeout 60_000
@type imported :: [TransactionAction.t()]
@impl Import.Runner
def ecto_schema_module, do: TransactionAction
@impl Import.Runner
def option_key, do: :transaction_actions
@impl Import.Runner
def imported_table_row do
%{
value_type: "[#{ecto_schema_module()}.t()]",
value_description: "List of `t:#{ecto_schema_module()}.t/0`s"
}
end
@impl Import.Runner
def run(multi, changes_list, %{timestamps: timestamps} = options) do
insert_options =
options
|> Map.get(option_key(), %{})
|> Map.take(~w(on_conflict timeout)a)
|> Map.put_new(:timeout, @timeout)
|> Map.put(:timestamps, timestamps)
Multi.run(multi, :insert_transaction_actions, fn repo, _ ->
Instrumenter.block_import_stage_runner(
fn -> insert(repo, changes_list, insert_options) end,
:block_referencing,
:transaction_actions,
:transaction_actions
)
end)
end
@impl Import.Runner
def timeout, do: @timeout
@spec insert(Repo.t(), [map()], %{required(:timeout) => timeout(), required(:timestamps) => Import.timestamps()}) ::
{:ok, [TransactionAction.t()]}
| {:error, [Changeset.t()]}
def insert(repo, changes_list, %{timeout: timeout, timestamps: timestamps} = _options) when is_list(changes_list) do
# Enforce TransactionAction ShareLocks order (see docs: sharelock.md)
ordered_changes_list = Enum.sort_by(changes_list, &{&1.hash, &1.log_index})
{:ok, inserted} =
Import.insert_changes_list(
repo,
ordered_changes_list,
for: TransactionAction,
returning: true,
timeout: timeout,
timestamps: timestamps,
on_conflict: :nothing
)
{:ok, inserted}
end
end

@ -17,7 +17,8 @@ defmodule Explorer.Chain.Import.Stage.BlockReferencing do
Runner.Logs, Runner.Logs,
Runner.Tokens, Runner.Tokens,
Runner.TokenTransfers, Runner.TokenTransfers,
Runner.Address.TokenBalances Runner.Address.TokenBalances,
Runner.TransactionActions
] ]
@impl Stage @impl Stage

@ -26,6 +26,7 @@ defmodule Explorer.Chain.Transaction do
SmartContract, SmartContract,
TokenTransfer, TokenTransfer,
Transaction, Transaction,
TransactionAction,
Wei Wei
} }
@ -261,6 +262,7 @@ defmodule Explorer.Chain.Transaction do
has_many(:internal_transactions, InternalTransaction, foreign_key: :transaction_hash) has_many(:internal_transactions, InternalTransaction, foreign_key: :transaction_hash)
has_many(:logs, Log, foreign_key: :transaction_hash) has_many(:logs, Log, foreign_key: :transaction_hash)
has_many(:token_transfers, TokenTransfer, foreign_key: :transaction_hash) has_many(:token_transfers, TokenTransfer, foreign_key: :transaction_hash)
has_many(:transaction_actions, TransactionAction, foreign_key: :hash, preload_order: [asc: :log_index])
belongs_to( belongs_to(
:to_address, :to_address,

@ -0,0 +1,70 @@
defmodule Explorer.Chain.TransactionAction do
@moduledoc "Models transaction action."
use Explorer.Schema
alias Explorer.Chain.{
Hash,
Transaction
}
@required_attrs ~w(hash protocol data type log_index)a
@supported_protocols [:uniswap_v3, :opensea_v1_1, :wrapping, :approval, :zkbob]
@typedoc """
* `hash` - transaction hash
* `protocol` - name of the action protocol (see possible values for Enum of the db table field)
* `data` - transaction action details (json formatted)
* `type` - type of the action protocol (see possible values for Enum of the db table field)
* `log_index` - index of the action for sorting (taken from log.index)
"""
@type t :: %__MODULE__{
hash: Hash.t(),
protocol: String.t(),
data: map(),
type: String.t(),
log_index: non_neg_integer()
}
@primary_key false
schema "transaction_actions" do
field(:protocol, Ecto.Enum, values: @supported_protocols)
field(:data, :map)
field(:type, Ecto.Enum,
values: [
:mint_nft,
:mint,
:burn,
:collect,
:swap,
:sale,
:cancel,
:transfer,
:wrap,
:unwrap,
:approve,
:revoke,
:withdraw,
:deposit
]
)
field(:log_index, :integer, primary_key: true)
belongs_to(:transaction, Transaction, foreign_key: :hash, primary_key: true, references: :hash, type: Hash.Full)
timestamps()
end
def changeset(%__MODULE__{} = tx_actions, attrs \\ %{}) do
tx_actions
|> cast(attrs, @required_attrs)
|> validate_required(@required_attrs)
|> foreign_key_constraint(:hash)
end
def supported_protocols do
@supported_protocols
end
end

@ -0,0 +1,31 @@
defmodule Explorer.Repo.Migrations.AddTransactionActionsTable do
use Ecto.Migration
def change do
execute(
"CREATE TYPE transaction_actions_protocol AS ENUM ('uniswap_v3', 'opensea_v1_1', 'wrapping', 'approval', 'zkbob')",
"DROP TYPE transaction_actions_protocol"
)
execute(
"CREATE TYPE transaction_actions_type AS ENUM ('mint_nft', 'mint', 'burn', 'collect', 'swap', 'sale', 'cancel', 'transfer', 'wrap', 'unwrap', 'approve', 'revoke', 'withdraw', 'deposit')",
"DROP TYPE transaction_actions_type"
)
create table(:transaction_actions, primary_key: false) do
add(:hash, references(:transactions, column: :hash, on_delete: :delete_all, on_update: :update_all, type: :bytea),
null: false,
primary_key: true
)
add(:protocol, :transaction_actions_protocol, null: false)
add(:data, :map, default: %{}, null: false)
add(:type, :transaction_actions_type, null: false)
add(:log_index, :integer, null: false, primary_key: true)
timestamps(null: false, type: :utc_datetime_usec)
end
create(index(:transaction_actions, [:protocol, :type]))
end
end

@ -21,6 +21,7 @@ Some data has to be extracted from already fetched data, and there're several tr
- `address_coin_balances`: detects coin balance-changing entities (transactions, minted blocks, etc) to create coin balance entities for further fetching - `address_coin_balances`: detects coin balance-changing entities (transactions, minted blocks, etc) to create coin balance entities for further fetching
- `token_transfers`: parses logs to extract token transfers - `token_transfers`: parses logs to extract token transfers
- `mint_transfers`: parses logs to extract token mint transfers - `mint_transfers`: parses logs to extract token mint transfers
- `transaction_actions`: parses logs to extract transaction actions
- `address_token_balances`: creates token balance entities for futher fetching, based on detected token transfers - `address_token_balances`: creates token balance entities for futher fetching, based on detected token transfers
- `blocks`: extracts block signer hash from additional data for Clique chains - `blocks`: extracts block signer hash from additional data for Clique chains
@ -29,6 +30,7 @@ Some data has to be extracted from already fetched data, and there're several tr
- `pending_transaction`: fetches pending transactions (i.e. not yet collated into a block) every second (`pending_transaction_interval`) - `pending_transaction`: fetches pending transactions (i.e. not yet collated into a block) every second (`pending_transaction_interval`)
- `block/realtime`: listens for new blocks from websocket and polls node for new blocks, imports new ones one by one - `block/realtime`: listens for new blocks from websocket and polls node for new blocks, imports new ones one by one
- `block/catchup`: gets unfetched ranges of blocks, imports them in batches - `block/catchup`: gets unfetched ranges of blocks, imports them in batches
- `transaction_action`: optionally fetches/rewrites transaction actions for old blocks (in a given range of blocks for given protocols)
Both block fetchers retrieve/extract the blocks themselves and the following additional data: Both block fetchers retrieve/extract the blocks themselves and the following additional data:
@ -36,6 +38,7 @@ Both block fetchers retrieve/extract the blocks themselves and the following add
- `transactions` - `transactions`
- `logs` - `logs`
- `token_transfers` - `token_transfers`
- `transaction_actions`
- `addresses` - `addresses`
The following stubs for further async fetching are inserted as well: The following stubs for further async fetching are inserted as well:

@ -37,7 +37,8 @@ defmodule Indexer.Block.Fetcher do
Addresses, Addresses,
AddressTokenBalances, AddressTokenBalances,
MintTransfers, MintTransfers,
TokenTransfers TokenTransfers,
TransactionActions
} }
alias Indexer.Transform.Blocks, as: TransformBlocks alias Indexer.Transform.Blocks, as: TransformBlocks
@ -137,6 +138,7 @@ defmodule Indexer.Block.Fetcher do
%{logs: logs, receipts: receipts} = receipt_params, %{logs: logs, receipts: receipts} = receipt_params,
transactions_with_receipts = Receipts.put(transactions_params_without_receipts, receipts), transactions_with_receipts = Receipts.put(transactions_params_without_receipts, receipts),
%{token_transfers: token_transfers, tokens: tokens} = TokenTransfers.parse(logs), %{token_transfers: token_transfers, tokens: tokens} = TokenTransfers.parse(logs),
%{transaction_actions: transaction_actions} = TransactionActions.parse(logs),
%{mint_transfers: mint_transfers} = MintTransfers.parse(logs), %{mint_transfers: mint_transfers} = MintTransfers.parse(logs),
%FetchedBeneficiaries{params_set: beneficiary_params_set, errors: beneficiaries_errors} = %FetchedBeneficiaries{params_set: beneficiary_params_set, errors: beneficiaries_errors} =
fetch_beneficiaries(blocks, transactions_with_receipts, json_rpc_named_arguments), fetch_beneficiaries(blocks, transactions_with_receipts, json_rpc_named_arguments),
@ -147,7 +149,8 @@ defmodule Indexer.Block.Fetcher do
logs: logs, logs: logs,
mint_transfers: mint_transfers, mint_transfers: mint_transfers,
token_transfers: token_transfers, token_transfers: token_transfers,
transactions: transactions_with_receipts transactions: transactions_with_receipts,
transaction_actions: transaction_actions
}), }),
coin_balances_params_set = coin_balances_params_set =
%{ %{
@ -166,6 +169,8 @@ defmodule Indexer.Block.Fetcher do
beneficiaries_with_gas_payment = beneficiaries_with_gas_payment =
beneficiaries_with_gas_payment(blocks, beneficiary_params_set, transactions_with_receipts), beneficiaries_with_gas_payment(blocks, beneficiary_params_set, transactions_with_receipts),
address_token_balances = AddressTokenBalances.params_set(%{token_transfers_params: token_transfers}), address_token_balances = AddressTokenBalances.params_set(%{token_transfers_params: token_transfers}),
transaction_actions =
Enum.map(transaction_actions, fn action -> Map.put(action, :data, Map.delete(action.data, :block_number)) end),
{:ok, inserted} <- {:ok, inserted} <-
__MODULE__.import( __MODULE__.import(
state, state,
@ -180,7 +185,8 @@ defmodule Indexer.Block.Fetcher do
logs: %{params: logs}, logs: %{params: logs},
token_transfers: %{params: token_transfers}, token_transfers: %{params: token_transfers},
tokens: %{on_conflict: :nothing, params: tokens}, tokens: %{on_conflict: :nothing, params: tokens},
transactions: %{params: transactions_with_receipts} transactions: %{params: transactions_with_receipts},
transaction_actions: %{params: transaction_actions}
} }
) do ) do
Prometheus.Instrumenter.block_batch_fetch(fetch_time, callback_module) Prometheus.Instrumenter.block_batch_fetch(fetch_time, callback_module)

@ -0,0 +1,283 @@
defmodule Indexer.Fetcher.TransactionAction do
@moduledoc """
Fetches information about transaction actions.
"""
use GenServer
use Indexer.Fetcher
require Logger
import Ecto.Query,
only: [
from: 2
]
alias Explorer.{Chain, Repo}
alias Explorer.Chain.{Log, TransactionAction}
alias Indexer.Transform.{Addresses, TransactionActions}
@stage_first_block "tx_action_first_block"
@stage_next_block "tx_action_next_block"
@stage_last_block "tx_action_last_block"
defstruct first_block: nil, next_block: nil, last_block: nil, protocols: [], task: nil, pid: nil
def child_spec([init_arguments]) do
child_spec([init_arguments, []])
end
def child_spec([_init_arguments, _gen_server_options] = start_link_arguments) do
default = %{
id: __MODULE__,
start: {__MODULE__, :start_link, start_link_arguments}
}
Supervisor.child_spec(default, restart: :transient)
end
def start_link(arguments, gen_server_options \\ []) do
GenServer.start_link(__MODULE__, arguments, gen_server_options)
end
@impl GenServer
def init(opts) when is_list(opts) do
opts =
Application.get_all_env(:indexer)[__MODULE__]
|> Keyword.merge(opts)
first_block = Keyword.get(opts, :reindex_first_block)
last_block = Keyword.get(opts, :reindex_last_block)
cond do
!is_nil(first_block) and !is_nil(last_block) ->
init_fetching(opts, first_block, last_block)
is_nil(first_block) and !is_nil(last_block) ->
{:stop, "Please, specify the first block of the block range for #{__MODULE__}."}
!is_nil(first_block) and is_nil(last_block) ->
{:stop, "Please, specify the last block of the block range for #{__MODULE__}."}
true ->
:ignore
end
end
@impl GenServer
def handle_info(:fetch, %__MODULE__{} = state) do
task = Task.Supervisor.async_nolink(Indexer.Fetcher.TransactionAction.TaskSupervisor, fn -> task(state) end)
{:noreply, %__MODULE__{state | task: task}}
end
def handle_info(:stop_server, %__MODULE__{} = state) do
{:stop, :normal, state}
end
def handle_info({ref, _result}, %__MODULE__{task: %Task{ref: ref}} = state) do
Process.demonitor(ref, [:flush])
{:noreply, %__MODULE__{state | task: nil}}
end
def handle_info(
{:DOWN, ref, :process, pid, reason},
%__MODULE__{task: %Task{pid: pid, ref: ref}} = state
) do
if reason === :normal do
{:noreply, %__MODULE__{state | task: nil}}
else
Logger.metadata(fetcher: :transaction_action)
Logger.error(fn -> "Transaction action fetcher task exited due to #{inspect(reason)}. Rerunning..." end)
{:noreply, run_fetch(state)}
end
end
defp run_fetch(state) do
pid = self()
Process.send(pid, :fetch, [])
%__MODULE__{state | task: nil, pid: pid}
end
defp task(
%__MODULE__{
first_block: first_block,
next_block: next_block,
last_block: last_block,
protocols: protocols,
pid: pid
} = _state
) do
Logger.metadata(fetcher: :transaction_action)
block_range = Range.new(next_block, first_block, -1)
block_range_init_length = last_block - first_block + 1
for block_number <- block_range do
query =
from(
log in Log,
where: log.block_number == ^block_number,
select: log
)
%{transaction_actions: transaction_actions} =
query
|> Repo.all()
|> TransactionActions.parse(protocols)
addresses =
Addresses.extract_addresses(%{
transaction_actions: transaction_actions
})
tx_actions =
Enum.map(transaction_actions, fn action ->
Map.put(action, :data, Map.delete(action.data, :block_number))
end)
{:ok, _} =
Chain.import(%{
addresses: %{params: addresses, on_conflict: :nothing},
transaction_actions: %{params: tx_actions},
timeout: :infinity
})
blocks_processed = last_block - block_number + 1
progress_percentage =
blocks_processed
|> Decimal.div(block_range_init_length)
|> Decimal.mult(100)
|> Decimal.round(2)
|> Decimal.to_string()
next_block_new = block_number - 1
Logger.info(
"Block #{block_number} handled successfully. Progress: #{progress_percentage}%. Initial block range: #{first_block}..#{last_block}." <>
if(next_block_new >= first_block, do: " Remaining block range: #{first_block}..#{next_block_new}", else: "")
)
if block_number == next_block do
{:ok, _} =
Chain.upsert_last_fetched_counter(%{
counter_type: @stage_first_block,
value: first_block
})
{:ok, _} =
Chain.upsert_last_fetched_counter(%{
counter_type: @stage_last_block,
value: last_block
})
end
{:ok, _} =
Chain.upsert_last_fetched_counter(%{
counter_type: @stage_next_block,
value: next_block_new
})
end
Process.send(pid, :stop_server, [])
:ok
end
defp init_fetching(opts, first_block, last_block) do
Logger.metadata(fetcher: :transaction_action)
first_block = parse_integer(first_block)
last_block = parse_integer(last_block)
cond do
is_nil(first_block) or is_nil(last_block) or first_block <= 0 or last_block <= 0 or first_block > last_block ->
{:stop, "Correct block range must be provided to #{__MODULE__}."}
last_block > (max_block_number = Chain.fetch_max_block_number()) ->
{:stop,
"The last block number (#{last_block}) provided to #{__MODULE__} is incorrect as it exceeds max block number available in DB (#{max_block_number})."}
true ->
supported_protocols =
TransactionAction.supported_protocols()
|> Enum.map(&Atom.to_string(&1))
protocols =
opts
|> Keyword.get(:reindex_protocols, "")
|> String.trim()
|> String.split(",")
|> Enum.map(&String.trim(&1))
|> Enum.filter(&Enum.member?(supported_protocols, &1))
next_block = get_next_block(first_block, last_block, protocols)
state =
%__MODULE__{
first_block: first_block,
next_block: next_block,
last_block: last_block,
protocols: protocols
}
|> run_fetch()
{:ok, state}
end
end
defp get_next_block(first_block, last_block, protocols) do
first_block_from_stage = get_stage_block(@stage_first_block)
last_block_from_stage = get_stage_block(@stage_last_block)
{stage_first_block, stage_next_block, stage_last_block} =
if first_block_from_stage == 0 or last_block_from_stage == 0 do
{first_block, last_block, last_block}
else
{first_block_from_stage, get_stage_block(@stage_next_block), last_block_from_stage}
end
next_block =
if Decimal.eq?(stage_first_block, first_block) and Decimal.eq?(stage_last_block, last_block) do
stage_next_block
else
last_block
end
if next_block < first_block do
Logger.warn(
"It seems #{__MODULE__} already finished work for the block range #{first_block}..#{last_block} and " <>
if(Enum.empty?(protocols),
do: "all supported protocols.",
else: "the following protocols: #{Enum.join(protocols, ", ")}."
) <>
" To run it again for a different block range, please change the range through environment variables."
)
else
Logger.info(
"Running #{__MODULE__} for the block range #{first_block}..#{next_block} and " <>
if(Enum.empty?(protocols),
do: "all supported protocols.",
else: "the following protocols: #{Enum.join(protocols, ", ")}."
) <> if(next_block < last_block, do: " Initial block range: #{first_block}..#{last_block}.", else: "")
)
end
next_block
end
defp get_stage_block(type) do
type
|> Chain.get_last_fetched_counter()
|> Decimal.to_integer()
rescue
_e in Ecto.NoResultsError -> 0
end
defp parse_integer(integer_string) do
case Integer.parse(integer_string) do
{integer, ""} -> integer
_ -> nil
end
end
end

@ -28,6 +28,7 @@ defmodule Indexer.Supervisor do
TokenInstance, TokenInstance,
TokenTotalSupplyOnDemand, TokenTotalSupplyOnDemand,
TokenUpdater, TokenUpdater,
TransactionAction,
UncleBlock UncleBlock
} }
@ -120,6 +121,7 @@ defmodule Indexer.Supervisor do
[ [
[json_rpc_named_arguments: json_rpc_named_arguments, memory_monitor: memory_monitor] [json_rpc_named_arguments: json_rpc_named_arguments, memory_monitor: memory_monitor]
]}, ]},
configure(TransactionAction.Supervisor, [[memory_monitor: memory_monitor]]),
{ContractCode.Supervisor, {ContractCode.Supervisor,
[[json_rpc_named_arguments: json_rpc_named_arguments, memory_monitor: memory_monitor]]}, [[json_rpc_named_arguments: json_rpc_named_arguments, memory_monitor: memory_monitor]]},
{TokenBalance.Supervisor, {TokenBalance.Supervisor,

@ -410,6 +410,11 @@ defmodule Indexer.Transform.Addresses do
required(:block_number) => non_neg_integer() required(:block_number) => non_neg_integer()
} }
], ],
optional(:transaction_actions) => [
%{
required(:data) => map()
}
],
optional(:mint_transfers) => [ optional(:mint_transfers) => [
%{ %{
required(:from_address_hash) => String.t(), required(:from_address_hash) => String.t(),
@ -432,7 +437,18 @@ defmodule Indexer.Transform.Addresses do
(entity_items = Map.get(fetched_data, entity_key)) != nil, (entity_items = Map.get(fetched_data, entity_key)) != nil,
do: extract_addresses_from_collection(entity_items, entity_fields, state) do: extract_addresses_from_collection(entity_items, entity_fields, state)
tx_actions_addresses =
fetched_data
|> Map.get(:transaction_actions, [])
|> Enum.map(fn tx_action ->
tx_action.data
|> Map.get(:block_number)
|> find_tx_action_addresses(tx_action.data)
end)
|> List.flatten()
addresses addresses
|> Enum.concat(tx_actions_addresses)
|> List.flatten() |> List.flatten()
|> merge_addresses() |> merge_addresses()
end end
@ -442,6 +458,25 @@ defmodule Indexer.Transform.Addresses do
def extract_addresses_from_item(item, fields, state), do: Enum.flat_map(fields, &extract_fields(&1, item, state)) def extract_addresses_from_item(item, fields, state), do: Enum.flat_map(fields, &extract_fields(&1, item, state))
defp find_tx_action_addresses(block_number, data, accumulator \\ [])
defp find_tx_action_addresses(block_number, data, accumulator) when is_map(data) or is_list(data) do
Enum.reduce(data, accumulator, fn
{_, value}, acc -> find_tx_action_addresses(block_number, value, acc)
value, acc -> find_tx_action_addresses(block_number, value, acc)
end)
end
defp find_tx_action_addresses(block_number, value, accumulator) when is_binary(value) do
if is_address?(value) do
[%{:fetched_coin_balance_block_number => block_number, :hash => value} | accumulator]
else
accumulator
end
end
defp find_tx_action_addresses(_block_number, _value, accumulator), do: accumulator
def merge_addresses(addresses) when is_list(addresses) do def merge_addresses(addresses) when is_list(addresses) do
addresses addresses
|> Enum.group_by(fn address -> address.hash end) |> Enum.group_by(fn address -> address.hash end)
@ -526,4 +561,8 @@ defmodule Indexer.Transform.Addresses do
defp max_nil_last(first_integer, second_integer) defp max_nil_last(first_integer, second_integer)
when is_integer(first_integer) and is_integer(second_integer), when is_integer(first_integer) and is_integer(second_integer),
do: max(first_integer, second_integer) do: max(first_integer, second_integer)
defp is_address?(value) when is_binary(value) do
String.match?(value, ~r/^0x[[:xdigit:]]{40}$/i)
end
end end

@ -0,0 +1,775 @@
defmodule Indexer.Transform.TransactionActions do
@moduledoc """
Helper functions for transforming data for transaction actions.
"""
require Logger
import Ecto.Query, only: [from: 2]
alias ABI.TypeDecoder
alias Explorer.Chain.Cache.NetVersion
alias Explorer.Chain.{Address, Data, Hash, Token, TransactionAction}
alias Explorer.Repo
alias Explorer.SmartContract.Reader
@mainnet 1
@goerli 5
@optimism 10
@polygon 137
# @gnosis 100
@default_max_token_cache_size 100_000
@burn_address "0x0000000000000000000000000000000000000000"
@uniswap_v3_positions_nft "0xC36442b4a4522E871399CD717aBDD847Ab11FE88"
@uniswap_v3_factory "0x1F98431c8aD98523631AE4a59f267346ea31F984"
@uniswap_v3_factory_abi [
%{
"inputs" => [
%{"internalType" => "address", "name" => "", "type" => "address"},
%{"internalType" => "address", "name" => "", "type" => "address"},
%{"internalType" => "uint24", "name" => "", "type" => "uint24"}
],
"name" => "getPool",
"outputs" => [%{"internalType" => "address", "name" => "", "type" => "address"}],
"stateMutability" => "view",
"type" => "function"
}
]
@uniswap_v3_pool_abi [
%{
"inputs" => [],
"name" => "fee",
"outputs" => [%{"internalType" => "uint24", "name" => "", "type" => "uint24"}],
"stateMutability" => "view",
"type" => "function"
},
%{
"inputs" => [],
"name" => "token0",
"outputs" => [%{"internalType" => "address", "name" => "", "type" => "address"}],
"stateMutability" => "view",
"type" => "function"
},
%{
"inputs" => [],
"name" => "token1",
"outputs" => [%{"internalType" => "address", "name" => "", "type" => "address"}],
"stateMutability" => "view",
"type" => "function"
}
]
@erc20_abi [
%{
"constant" => true,
"inputs" => [],
"name" => "symbol",
"outputs" => [%{"name" => "", "type" => "string"}],
"payable" => false,
"stateMutability" => "view",
"type" => "function"
},
%{
"constant" => true,
"inputs" => [],
"name" => "decimals",
"outputs" => [%{"name" => "", "type" => "uint8"}],
"payable" => false,
"stateMutability" => "view",
"type" => "function"
}
]
# 32-byte signature of the event Transfer(address indexed from, address indexed to, uint256 indexed tokenId)
@uniswap_v3_transfer_nft_event "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"
# 32-byte signature of the event Mint(address sender, address indexed owner, int24 indexed tickLower, int24 indexed tickUpper, uint128 amount, uint256 amount0, uint256 amount1)
@uniswap_v3_mint_event "0x7a53080ba414158be7ec69b987b5fb7d07dee101fe85488f0853ae16239d0bde"
# 32-byte signature of the event Burn(address indexed owner, int24 indexed tickLower, int24 indexed tickUpper, uint128 amount, uint256 amount0, uint256 amount1)
@uniswap_v3_burn_event "0x0c396cd989a39f4459b5fa1aed6a9a8dcdbc45908acfd67e028cd568da98982c"
# 32-byte signature of the event Collect(address indexed owner, address recipient, int24 indexed tickLower, int24 indexed tickUpper, uint128 amount0, uint128 amount1)
@uniswap_v3_collect_event "0x70935338e69775456a85ddef226c395fb668b63fa0115f5f20610b388e6ca9c0"
# 32-byte signature of the event Swap(address indexed sender, address indexed recipient, int256 amount0, int256 amount1, uint160 sqrtPriceX96, uint128 liquidity, int24 tick);
@uniswap_v3_swap_event "0xc42079f94a6350d7e6235f29174924f928cc2ac818eb64fed8004e115fbcca67"
@doc """
Returns a list of transaction actions given a list of logs.
"""
def parse(logs, protocols_to_rewrite \\ []) do
if Application.get_env(:indexer, Indexer.Fetcher.TransactionAction.Supervisor)[:enabled] do
actions = []
chain_id = NetVersion.get_version()
logs
|> logs_group_by_txs()
|> clear_actions(protocols_to_rewrite)
# create tokens cache if not exists
if :ets.whereis(:tx_actions_tokens_data_cache) == :undefined do
:ets.new(:tx_actions_tokens_data_cache, [
:set,
:named_table,
:public,
read_concurrency: true,
write_concurrency: true
])
end
# handle uniswap v3
tx_actions =
if Enum.member?([@mainnet, @goerli, @optimism, @polygon], chain_id) and
(Enum.empty?(protocols_to_rewrite) or Enum.member?(protocols_to_rewrite, "uniswap_v3")) do
logs
|> uniswap_filter_logs()
|> logs_group_by_txs()
|> uniswap(actions, chain_id)
else
actions
end
%{transaction_actions: tx_actions}
else
%{transaction_actions: []}
end
end
defp uniswap(logs_grouped, actions, chain_id) do
# create a list of UniswapV3Pool legitimate contracts
legitimate = uniswap_legitimate_pools(logs_grouped)
# iterate for each transaction
Enum.reduce(logs_grouped, actions, fn {tx_hash, tx_logs}, actions_acc ->
# trying to find `mint_nft` actions
actions_acc = uniswap_handle_mint_nft_actions(tx_hash, tx_logs, actions_acc)
# go through other actions
Enum.reduce(tx_logs, actions_acc, fn log, acc ->
acc ++ uniswap_handle_action(log, legitimate, chain_id)
end)
end)
end
defp uniswap_clarify_token_symbol(symbol, chain_id) do
if symbol == "WETH" && Enum.member?([@mainnet, @goerli, @optimism], chain_id) do
"Ether"
else
symbol
end
end
defp uniswap_filter_logs(logs) do
logs
|> Enum.filter(fn log ->
first_topic = String.downcase(log.first_topic)
Enum.member?(
[
@uniswap_v3_mint_event,
@uniswap_v3_burn_event,
@uniswap_v3_collect_event,
@uniswap_v3_swap_event
],
first_topic
) ||
(first_topic == @uniswap_v3_transfer_nft_event &&
String.downcase(address_hash_to_string(log.address_hash)) == String.downcase(@uniswap_v3_positions_nft))
end)
end
defp uniswap_handle_action(log, legitimate, chain_id) do
first_topic = String.downcase(log.first_topic)
with false <- first_topic == @uniswap_v3_transfer_nft_event,
# check UniswapV3Pool contract is legitimate
pool_address <- String.downcase(address_hash_to_string(log.address_hash)),
false <- Enum.empty?(legitimate[pool_address]),
# this is legitimate uniswap pool, so handle this event
token_address <- legitimate[pool_address],
token_data <- get_token_data(token_address),
false <- token_data === false do
case first_topic do
@uniswap_v3_mint_event ->
# this is Mint event
uniswap_handle_mint_event(log, token_address, token_data, chain_id)
@uniswap_v3_burn_event ->
# this is Burn event
uniswap_handle_burn_event(log, token_address, token_data, chain_id)
@uniswap_v3_collect_event ->
# this is Collect event
uniswap_handle_collect_event(log, token_address, token_data, chain_id)
@uniswap_v3_swap_event ->
# this is Swap event
uniswap_handle_swap_event(log, token_address, token_data, chain_id)
_ ->
[]
end
else
_ -> []
end
end
defp uniswap_handle_mint_nft_actions(tx_hash, tx_logs, actions_acc) do
first_log = Enum.at(tx_logs, 0)
local_acc =
tx_logs
|> Enum.reduce(%{}, fn log, acc ->
first_topic = String.downcase(log.first_topic)
if first_topic == @uniswap_v3_transfer_nft_event do
# This is Transfer event for NFT
from = truncate_address_hash(log.second_topic)
if from == @burn_address do
to = truncate_address_hash(log.third_topic)
[token_id] = decode_data(log.fourth_topic, [{:uint, 256}])
mint_nft_ids = Map.put_new(acc, to, %{ids: [], log_index: log.index})
Map.put(mint_nft_ids, to, %{
ids: Enum.reverse([to_string(token_id) | Enum.reverse(mint_nft_ids[to].ids)]),
log_index: mint_nft_ids[to].log_index
})
else
acc
end
else
acc
end
end)
|> Enum.reduce([], fn {to, %{ids: ids, log_index: log_index}}, acc ->
action = %{
hash: tx_hash,
protocol: "uniswap_v3",
data: %{
name: "Uniswap V3: Positions NFT",
symbol: "UNI-V3-POS",
address: @uniswap_v3_positions_nft,
to: Address.checksum(to),
ids: ids,
block_number: first_log.block_number
},
type: "mint_nft",
log_index: log_index
}
[action | acc]
end)
|> Enum.reverse()
actions_acc ++ local_acc
end
defp uniswap_handle_burn_event(log, token_address, token_data, chain_id) do
[_amount, amount0, amount1] = decode_data(log.data, [{:uint, 128}, {:uint, 256}, {:uint, 256}])
uniswap_handle_event("burn", amount0, amount1, log, token_address, token_data, chain_id)
end
defp uniswap_handle_collect_event(log, token_address, token_data, chain_id) do
[_recipient, amount0, amount1] = decode_data(log.data, [:address, {:uint, 128}, {:uint, 128}])
uniswap_handle_event("collect", amount0, amount1, log, token_address, token_data, chain_id)
end
defp uniswap_handle_mint_event(log, token_address, token_data, chain_id) do
[_sender, _amount, amount0, amount1] = decode_data(log.data, [:address, {:uint, 128}, {:uint, 256}, {:uint, 256}])
uniswap_handle_event("mint", amount0, amount1, log, token_address, token_data, chain_id)
end
defp uniswap_handle_swap_event(log, token_address, token_data, chain_id) do
[amount0, amount1, _sqrt_price_x96, _liquidity, _tick] =
decode_data(log.data, [{:int, 256}, {:int, 256}, {:uint, 160}, {:uint, 128}, {:int, 24}])
uniswap_handle_event("swap", amount0, amount1, log, token_address, token_data, chain_id)
end
defp uniswap_handle_swap_amounts(log, amount0, amount1, symbol0, symbol1, address0, address1) do
cond do
String.first(amount0) === "-" and String.first(amount1) !== "-" ->
{amount1, symbol1, address1, String.slice(amount0, 1, String.length(amount0) - 1), symbol0, address0, false}
String.first(amount1) === "-" and String.first(amount0) !== "-" ->
{amount0, symbol0, address0, String.slice(amount1, 1, String.length(amount1) - 1), symbol1, address1, false}
amount1 === "0" and String.first(amount0) !== "-" ->
{amount0, symbol0, address0, amount1, symbol1, address1, false}
true ->
Logger.error(
"Invalid Swap event in tx #{log.transaction_hash}. Log index: #{log.index}. amount0 = #{amount0}, amount1 = #{amount1}"
)
{amount0, symbol0, address0, amount1, symbol1, address1, true}
end
end
defp uniswap_handle_event(type, amount0, amount1, log, token_address, token_data, chain_id) do
address0 = Enum.at(token_address, 0)
decimals0 = token_data[address0].decimals
symbol0 = uniswap_clarify_token_symbol(token_data[address0].symbol, chain_id)
address1 = Enum.at(token_address, 1)
decimals1 = token_data[address1].decimals
symbol1 = uniswap_clarify_token_symbol(token_data[address1].symbol, chain_id)
amount0 = fractional(Decimal.new(amount0), Decimal.new(decimals0))
amount1 = fractional(Decimal.new(amount1), Decimal.new(decimals1))
{new_amount0, new_symbol0, new_address0, new_amount1, new_symbol1, new_address1, is_error} =
if type == "swap" do
uniswap_handle_swap_amounts(log, amount0, amount1, symbol0, symbol1, address0, address1)
else
{amount0, symbol0, address0, amount1, symbol1, address1, false}
end
if is_error do
[]
else
[
%{
hash: log.transaction_hash,
protocol: "uniswap_v3",
data: %{
amount0: new_amount0,
symbol0: new_symbol0,
address0: Address.checksum(new_address0),
amount1: new_amount1,
symbol1: new_symbol1,
address1: Address.checksum(new_address1),
block_number: log.block_number
},
type: type,
log_index: log.index
}
]
end
end
defp uniswap_legitimate_pools(logs_grouped) do
pools =
logs_grouped
|> Enum.reduce(%{}, fn {_tx_hash, tx_logs}, addresses_acc ->
tx_logs
|> Enum.filter(fn log ->
first_topic = String.downcase(log.first_topic)
first_topic != @uniswap_v3_transfer_nft_event
end)
|> Enum.reduce(addresses_acc, fn log, acc ->
pool_address = String.downcase(address_hash_to_string(log.address_hash))
Map.put_new(acc, pool_address, true)
end)
end)
req_resp = uniswap_request_tokens_and_fees(pools)
if req_resp === false do
%{}
else
case uniswap_request_get_pools(req_resp) do
{requests_get_pool, responses_get_pool} ->
requests_get_pool
|> Enum.zip(responses_get_pool)
|> Enum.reduce(%{}, fn {request, {_status, response} = _resp}, acc ->
response =
case response do
[item] -> item
items -> items
end
Map.put(
acc,
request.pool_address,
if request.pool_address == String.downcase(response) do
[token0, token1, _] = request.args
[token0, token1]
else
[]
end
)
end)
_ ->
%{}
end
end
end
defp uniswap_request_get_pools({requests_tokens_and_fees, responses_tokens_and_fees}) do
requests_get_pool =
requests_tokens_and_fees
|> Enum.zip(responses_tokens_and_fees)
|> Enum.reduce(%{}, fn {request, {_status, response} = _resp}, acc ->
response =
case response do
[item] -> item
items -> items
end
acc = Map.put_new(acc, request.contract_address, %{token0: "", token1: "", fee: ""})
item = Map.put(acc[request.contract_address], atomized_key(request.method_id), response)
Map.put(acc, request.contract_address, item)
end)
|> Enum.map(fn {pool_address, pool} ->
token0 = if is_address_correct?(pool.token0), do: String.downcase(pool.token0), else: @burn_address
token1 = if is_address_correct?(pool.token1), do: String.downcase(pool.token1), else: @burn_address
fee = if pool.fee == "", do: 0, else: pool.fee
# we will call getPool(token0, token1, fee) public getter
%{
pool_address: pool_address,
contract_address: @uniswap_v3_factory,
method_id: "1698ee82",
args: [token0, token1, fee]
}
end)
max_retries = Application.get_env(:explorer, :token_functions_reader_max_retries)
{responses_get_pool, error_messages} =
read_contracts_with_retries(requests_get_pool, @uniswap_v3_factory_abi, max_retries)
if !Enum.empty?(error_messages) or Enum.count(requests_get_pool) != Enum.count(responses_get_pool) do
Logger.error(
"Cannot read Uniswap V3 Factory contract getPool public getter. Error messages: #{Enum.join(error_messages, ", ")}"
)
false
else
{requests_get_pool, responses_get_pool}
end
end
defp uniswap_request_tokens_and_fees(pools) do
requests =
pools
|> Enum.map(fn {pool_address, _} ->
# we will call token0(), token1(), fee() public getters
Enum.map(["0dfe1681", "d21220a7", "ddca3f43"], fn method_id ->
%{
contract_address: pool_address,
method_id: method_id,
args: []
}
end)
end)
|> List.flatten()
max_retries = Application.get_env(:explorer, :token_functions_reader_max_retries)
{responses, error_messages} = read_contracts_with_retries(requests, @uniswap_v3_pool_abi, max_retries)
if !Enum.empty?(error_messages) or Enum.count(requests) != Enum.count(responses) do
Logger.error(
"Cannot read Uniswap V3 Pool contract public getters: token0(), token1(), fee(). Error messages: #{Enum.join(error_messages, ", ")}. Pools: #{Enum.join(Map.keys(pools), ", ")}"
)
false
else
{requests, responses}
end
end
defp atomized_key("token0"), do: :token0
defp atomized_key("token1"), do: :token1
defp atomized_key("fee"), do: :fee
defp atomized_key("getPool"), do: :getPool
defp atomized_key("symbol"), do: :symbol
defp atomized_key("decimals"), do: :decimals
defp atomized_key("0dfe1681"), do: :token0
defp atomized_key("d21220a7"), do: :token1
defp atomized_key("ddca3f43"), do: :fee
defp atomized_key("1698ee82"), do: :getPool
defp atomized_key("95d89b41"), do: :symbol
defp atomized_key("313ce567"), do: :decimals
defp clear_actions(logs_grouped, protocols_to_clear) do
logs_grouped
|> Enum.each(fn {tx_hash, _} ->
query =
if Enum.empty?(protocols_to_clear) do
from(ta in TransactionAction, where: ta.hash == ^tx_hash)
else
from(ta in TransactionAction, where: ta.hash == ^tx_hash and ta.protocol in ^protocols_to_clear)
end
Repo.delete_all(query)
end)
end
defp decode_data("0x", types) do
for _ <- types, do: nil
end
defp decode_data("0x" <> encoded_data, types) do
encoded_data
|> Base.decode16!(case: :mixed)
|> TypeDecoder.decode_raw(types)
end
defp decode_data(%Data{} = data, types) do
data
|> Data.to_string()
|> decode_data(types)
end
defp fractional(%Decimal{} = amount, %Decimal{} = decimals) do
amount.sign
|> Decimal.new(amount.coef, amount.exp - Decimal.to_integer(decimals))
|> Decimal.normalize()
|> Decimal.to_string(:normal)
end
defp get_max_token_cache_size do
case Application.get_env(:indexer, __MODULE__)[:max_token_cache_size] do
nil ->
@default_max_token_cache_size
"" ->
@default_max_token_cache_size
max_cache_size ->
if is_binary(max_cache_size), do: String.to_integer(max_cache_size), else: max_cache_size
end
end
defp get_token_data(token_addresses) do
# first, we're trying to read token data from the cache.
# if the cache is empty, we read that from DB.
# if tokens are not in the cache, nor in the DB, read them through RPC.
token_data =
token_addresses
|> get_token_data_from_cache()
|> get_token_data_from_db()
|> get_token_data_from_rpc()
if Enum.any?(token_data, fn {_, token} ->
is_nil(token.symbol) or token.symbol == "" or is_nil(token.decimals)
end) do
false
else
token_data
end
end
defp get_token_data_from_cache(token_addresses) do
token_addresses
|> Enum.reduce(%{}, fn address, acc ->
Map.put(
acc,
address,
with info when info != :undefined <- :ets.info(:tx_actions_tokens_data_cache),
[{_, value}] <- :ets.lookup(:tx_actions_tokens_data_cache, address) do
value
else
_ -> %{symbol: nil, decimals: nil}
end
)
end)
end
defp get_token_data_from_db(token_data_from_cache) do
# a list of token addresses which we should select from the database
select_tokens_from_db =
token_data_from_cache
|> Enum.reduce([], fn {address, data}, acc ->
if is_nil(data.symbol) or is_nil(data.decimals) do
[address | acc]
else
acc
end
end)
|> Enum.reverse()
if Enum.empty?(select_tokens_from_db) do
# we don't need to read data from db, so will use the cache
token_data_from_cache
else
# try to read token symbols and decimals from the database and then save to the cache
query =
from(
t in Token,
where: t.contract_address_hash in ^select_tokens_from_db,
select: {t.symbol, t.decimals, t.contract_address_hash}
)
query
|> Repo.all()
|> Enum.reduce(token_data_from_cache, fn {symbol, decimals, contract_address_hash}, token_data_acc ->
contract_address_hash = String.downcase(Hash.to_string(contract_address_hash))
symbol =
if is_nil(symbol) or symbol == "" do
# if db field is empty, take it from the cache
token_data_acc[contract_address_hash].symbol
else
symbol
end
decimals =
if is_nil(decimals) do
# if db field is empty, take it from the cache
token_data_acc[contract_address_hash].decimals
else
decimals
end
new_data = %{symbol: symbol, decimals: decimals}
put_token_data_to_cache(contract_address_hash, new_data)
Map.put(token_data_acc, contract_address_hash, new_data)
end)
end
end
defp get_token_data_from_rpc(token_data) do
token_addresses =
token_data
|> Enum.reduce([], fn {address, data}, acc ->
if is_nil(data.symbol) or data.symbol == "" or is_nil(data.decimals) do
[address | acc]
else
acc
end
end)
|> Enum.reverse()
if Enum.empty?(token_addresses) do
token_data
else
req_resp = get_token_data_request_symbol_decimals(token_addresses)
if req_resp === false do
token_data
else
{requests, responses} = req_resp
requests
|> Enum.zip(responses)
|> Enum.reduce(token_data, fn {request, {_status, response} = _resp}, token_data_acc ->
response =
case response do
[item] -> item
items -> items
end
data = token_data_acc[request.contract_address]
new_data =
if atomized_key(request.method_id) == :symbol do
%{data | symbol: response}
else
%{data | decimals: response}
end
put_token_data_to_cache(request.contract_address, new_data)
Map.put(token_data_acc, request.contract_address, new_data)
end)
end
end
end
defp get_token_data_request_symbol_decimals(token_addresses) do
requests =
token_addresses
|> Enum.map(fn address ->
# we will call symbol() and decimals() public getters
Enum.map(["95d89b41", "313ce567"], fn method_id ->
%{
contract_address: address,
method_id: method_id,
args: []
}
end)
end)
|> List.flatten()
max_retries = Application.get_env(:explorer, :token_functions_reader_max_retries)
{responses, error_messages} = read_contracts_with_retries(requests, @erc20_abi, max_retries)
if !Enum.empty?(error_messages) or Enum.count(requests) != Enum.count(responses) do
Logger.error(
"Cannot read symbol and decimals of an ERC-20 token contract. Error messages: #{Enum.join(error_messages, ", ")}. Addresses: #{Enum.join(token_addresses, ", ")}"
)
false
else
{requests, responses}
end
end
defp is_address_correct?(address) do
String.match?(address, ~r/^0x[[:xdigit:]]{40}$/i)
end
defp address_hash_to_string(hash) do
if is_binary(hash) do
hash
else
Hash.to_string(hash)
end
end
defp logs_group_by_txs(logs) do
logs
|> Enum.group_by(& &1.transaction_hash)
end
defp put_token_data_to_cache(address, data) do
if not :ets.member(:tx_actions_tokens_data_cache, address) do
# we need to add a new item to the cache, but don't exceed the limit
cache_size = :ets.info(:tx_actions_tokens_data_cache, :size)
how_many_to_remove = cache_size - get_max_token_cache_size() + 1
range = Range.new(1, how_many_to_remove, 1)
for _step <- range do
:ets.delete(:tx_actions_tokens_data_cache, :ets.first(:tx_actions_tokens_data_cache))
end
end
:ets.insert(:tx_actions_tokens_data_cache, {address, data})
end
defp read_contracts_with_retries(requests, abi, retries_left) when retries_left > 0 do
responses = Reader.query_contracts(requests, abi)
error_messages =
Enum.reduce(responses, [], fn {status, error_message}, acc ->
acc ++
if status == :error do
[error_message]
else
[]
end
end)
if Enum.empty?(error_messages) do
{responses, []}
else
retries_left = retries_left - 1
if retries_left == 0 do
{[], Enum.uniq(error_messages)}
else
read_contracts_with_retries(requests, abi, retries_left)
end
end
end
defp truncate_address_hash(nil), do: @burn_address
defp truncate_address_hash("0x000000000000000000000000" <> truncated_hash) do
"0x#{truncated_hash}"
end
end

@ -289,7 +289,7 @@ defmodule Indexer.Block.Catchup.FetcherTest do
} }
}) })
Process.sleep(1000) Process.sleep(3000)
assert count(Chain.Block) == 1 assert count(Chain.Block) == 1
assert count(Reward) == 0 assert count(Reward) == 0
@ -440,7 +440,7 @@ defmodule Indexer.Block.Catchup.FetcherTest do
} }
}) })
Process.sleep(1000) Process.sleep(3000)
assert count(Chain.Block) == 1 assert count(Chain.Block) == 1
assert count(Reward) == 0 assert count(Reward) == 0
@ -586,7 +586,7 @@ defmodule Indexer.Block.Catchup.FetcherTest do
} }
}) })
Process.sleep(1000) Process.sleep(3000)
assert count(Chain.Block) == 1 assert count(Chain.Block) == 1
assert count(Reward) == 0 assert count(Reward) == 0

@ -432,6 +432,17 @@ config :indexer,
trace_last_block: System.get_env("TRACE_LAST_BLOCK") || "", trace_last_block: System.get_env("TRACE_LAST_BLOCK") || "",
fetch_rewards_way: System.get_env("FETCH_REWARDS_WAY", "trace_block") fetch_rewards_way: System.get_env("FETCH_REWARDS_WAY", "trace_block")
config :indexer, Indexer.Fetcher.TransactionAction.Supervisor,
enabled: System.get_env("INDEXER_TX_ACTIONS_ENABLE", "false") == "true"
config :indexer, Indexer.Fetcher.TransactionAction,
reindex_first_block: System.get_env("INDEXER_TX_ACTIONS_REINDEX_FIRST_BLOCK"),
reindex_last_block: System.get_env("INDEXER_TX_ACTIONS_REINDEX_LAST_BLOCK"),
reindex_protocols: System.get_env("INDEXER_TX_ACTIONS_REINDEX_PROTOCOLS", "")
config :indexer, Indexer.Transform.TransactionActions,
max_token_cache_size: System.get_env("INDEXER_TX_ACTIONS_MAX_TOKEN_CACHE_SIZE")
{receipts_batch_size, _} = Integer.parse(System.get_env("INDEXER_RECEIPTS_BATCH_SIZE", "250")) {receipts_batch_size, _} = Integer.parse(System.get_env("INDEXER_RECEIPTS_BATCH_SIZE", "250"))
{receipts_concurrency, _} = Integer.parse(System.get_env("INDEXER_RECEIPTS_CONCURRENCY", "10")) {receipts_concurrency, _} = Integer.parse(System.get_env("INDEXER_RECEIPTS_CONCURRENCY", "10"))

@ -90,6 +90,11 @@ INDEXER_DISABLE_INTERNAL_TRANSACTIONS_FETCHER=false
# INDEXER_COIN_BALANCES_CONCURRENCY= # INDEXER_COIN_BALANCES_CONCURRENCY=
# INDEXER_RECEIPTS_BATCH_SIZE= # INDEXER_RECEIPTS_BATCH_SIZE=
# INDEXER_RECEIPTS_CONCURRENCY= # INDEXER_RECEIPTS_CONCURRENCY=
# INDEXER_TX_ACTIONS_ENABLE=
# INDEXER_TX_ACTIONS_MAX_TOKEN_CACHE_SIZE=
# INDEXER_TX_ACTIONS_REINDEX_FIRST_BLOCK=
# INDEXER_TX_ACTIONS_REINDEX_LAST_BLOCK=
# INDEXER_TX_ACTIONS_REINDEX_PROTOCOLS=
# TOKEN_ID_MIGRATION_FIRST_BLOCK= # TOKEN_ID_MIGRATION_FIRST_BLOCK=
# TOKEN_ID_MIGRATION_CONCURRENCY= # TOKEN_ID_MIGRATION_CONCURRENCY=
# TOKEN_ID_MIGRATION_BATCH_SIZE= # TOKEN_ID_MIGRATION_BATCH_SIZE=

@ -479,13 +479,28 @@ ifdef INDEXER_INTERNAL_TRANSACTIONS_TRACER_TYPE
BLOCKSCOUT_CONTAINER_PARAMS += -e 'INDEXER_INTERNAL_TRANSACTIONS_TRACER_TYPE=$(INDEXER_INTERNAL_TRANSACTIONS_TRACER_TYPE)' BLOCKSCOUT_CONTAINER_PARAMS += -e 'INDEXER_INTERNAL_TRANSACTIONS_TRACER_TYPE=$(INDEXER_INTERNAL_TRANSACTIONS_TRACER_TYPE)'
endif endif
ifdef TOKEN_ID_MIGRATION_FIRST_BLOCK ifdef TOKEN_ID_MIGRATION_FIRST_BLOCK
BLOCKSCOUT_CONTAINER_PARAMS += -e 'INDEXER_EMPTY_BLOCKS_SANITIZER_BATCH_SIZE=$(INDEXER_EMPTY_BLOCKS_SANITIZER_BATCH_SIZE)' BLOCKSCOUT_CONTAINER_PARAMS += -e 'TOKEN_ID_MIGRATION_FIRST_BLOCK=$(TOKEN_ID_MIGRATION_FIRST_BLOCK)'
endif endif
ifdef TOKEN_ID_MIGRATION_CONCURRENCY ifdef TOKEN_ID_MIGRATION_CONCURRENCY
BLOCKSCOUT_CONTAINER_PARAMS += -e 'INDEXER_EMPTY_BLOCKS_SANITIZER_BATCH_SIZE=$(INDEXER_EMPTY_BLOCKS_SANITIZER_BATCH_SIZE)' BLOCKSCOUT_CONTAINER_PARAMS += -e 'TOKEN_ID_MIGRATION_CONCURRENCY=$(TOKEN_ID_MIGRATION_CONCURRENCY)'
endif endif
ifdef TOKEN_ID_MIGRATION_BATCH_SIZE ifdef TOKEN_ID_MIGRATION_BATCH_SIZE
BLOCKSCOUT_CONTAINER_PARAMS += -e 'INDEXER_EMPTY_BLOCKS_SANITIZER_BATCH_SIZE=$(INDEXER_EMPTY_BLOCKS_SANITIZER_BATCH_SIZE)' BLOCKSCOUT_CONTAINER_PARAMS += -e 'TOKEN_ID_MIGRATION_BATCH_SIZE=$(TOKEN_ID_MIGRATION_BATCH_SIZE)'
endif
ifdef INDEXER_TX_ACTIONS_ENABLE
BLOCKSCOUT_CONTAINER_PARAMS += -e 'INDEXER_TX_ACTIONS_ENABLE=$(INDEXER_TX_ACTIONS_ENABLE)'
endif
ifdef INDEXER_TX_ACTIONS_MAX_TOKEN_CACHE_SIZE
BLOCKSCOUT_CONTAINER_PARAMS += -e 'INDEXER_TX_ACTIONS_MAX_TOKEN_CACHE_SIZE=$(INDEXER_TX_ACTIONS_MAX_TOKEN_CACHE_SIZE)'
endif
ifdef INDEXER_TX_ACTIONS_REINDEX_FIRST_BLOCK
BLOCKSCOUT_CONTAINER_PARAMS += -e 'INDEXER_TX_ACTIONS_REINDEX_FIRST_BLOCK=$(INDEXER_TX_ACTIONS_REINDEX_FIRST_BLOCK)'
endif
ifdef INDEXER_TX_ACTIONS_REINDEX_LAST_BLOCK
BLOCKSCOUT_CONTAINER_PARAMS += -e 'INDEXER_TX_ACTIONS_REINDEX_LAST_BLOCK=$(INDEXER_TX_ACTIONS_REINDEX_LAST_BLOCK)'
endif
ifdef INDEXER_TX_ACTIONS_REINDEX_PROTOCOLS
BLOCKSCOUT_CONTAINER_PARAMS += -e 'INDEXER_TX_ACTIONS_REINDEX_PROTOCOLS=$(INDEXER_TX_ACTIONS_REINDEX_PROTOCOLS)'
endif endif
ifdef SECRET_KEY_BASE ifdef SECRET_KEY_BASE
BLOCKSCOUT_CONTAINER_PARAMS += -e 'SECRET_KEY_BASE=$(SECRET_KEY_BASE)' BLOCKSCOUT_CONTAINER_PARAMS += -e 'SECRET_KEY_BASE=$(SECRET_KEY_BASE)'

Loading…
Cancel
Save