Restricted list of addresses

pull/3311/head
Victor Baranov 4 years ago
parent 75912f624f
commit 836c3a4813
  1. 1
      CHANGELOG.md
  2. 4
      apps/block_scout_web/config/config.exs
  3. 9
      apps/block_scout_web/lib/block_scout_web/channels/address_channel.ex
  4. 9
      apps/block_scout_web/lib/block_scout_web/controllers/address_coin_balance_by_day_controller.ex
  5. 16
      apps/block_scout_web/lib/block_scout_web/controllers/address_coin_balance_controller.ex
  6. 9
      apps/block_scout_web/lib/block_scout_web/controllers/address_contract_controller.ex
  7. 4
      apps/block_scout_web/lib/block_scout_web/controllers/address_controller.ex
  8. 9
      apps/block_scout_web/lib/block_scout_web/controllers/address_decompiled_contract_controller.ex
  9. 14
      apps/block_scout_web/lib/block_scout_web/controllers/address_internal_transaction_controller.ex
  10. 10
      apps/block_scout_web/lib/block_scout_web/controllers/address_logs_controller.ex
  11. 6
      apps/block_scout_web/lib/block_scout_web/controllers/address_read_contract_controller.ex
  12. 6
      apps/block_scout_web/lib/block_scout_web/controllers/address_read_proxy_controller.ex
  13. 6
      apps/block_scout_web/lib/block_scout_web/controllers/address_token_balance_controller.ex
  14. 16
      apps/block_scout_web/lib/block_scout_web/controllers/address_token_controller.ex
  15. 28
      apps/block_scout_web/lib/block_scout_web/controllers/address_token_transfer_controller.ex
  16. 14
      apps/block_scout_web/lib/block_scout_web/controllers/address_transaction_controller.ex
  17. 16
      apps/block_scout_web/lib/block_scout_web/controllers/address_validation_controller.ex
  18. 6
      apps/block_scout_web/lib/block_scout_web/controllers/address_write_contract_controller.ex
  19. 6
      apps/block_scout_web/lib/block_scout_web/controllers/address_write_proxy_controller.ex
  20. 15
      apps/block_scout_web/lib/block_scout_web/controllers/tokens/holder_controller.ex
  21. 15
      apps/block_scout_web/lib/block_scout_web/controllers/tokens/inventory_controller.ex
  22. 9
      apps/block_scout_web/lib/block_scout_web/controllers/tokens/read_contract_controller.ex
  23. 3
      apps/block_scout_web/lib/block_scout_web/controllers/tokens/token_controller.ex
  24. 15
      apps/block_scout_web/lib/block_scout_web/controllers/tokens/transfer_controller.ex
  25. 13
      apps/block_scout_web/lib/block_scout_web/controllers/transaction_controller.ex
  26. 53
      apps/block_scout_web/lib/block_scout_web/controllers/transaction_internal_transaction_controller.ex
  27. 24
      apps/block_scout_web/lib/block_scout_web/controllers/transaction_log_controller.ex
  28. 14
      apps/block_scout_web/lib/block_scout_web/controllers/transaction_raw_trace_controller.ex
  29. 61
      apps/block_scout_web/lib/block_scout_web/controllers/transaction_token_transfer_controller.ex
  30. 2
      apps/block_scout_web/lib/block_scout_web/templates/address/_balance_card.html.eex
  31. 26
      apps/block_scout_web/lib/block_scout_web/templates/address/_tabs.html.eex
  32. 2
      apps/block_scout_web/lib/block_scout_web/templates/address_coin_balance/index.html.eex
  33. 16
      apps/block_scout_web/lib/block_scout_web/templates/address_internal_transaction/index.html.eex
  34. 16
      apps/block_scout_web/lib/block_scout_web/templates/address_token_transfer/index.html.eex
  35. 16
      apps/block_scout_web/lib/block_scout_web/templates/address_transaction/index.html.eex
  36. 2
      apps/block_scout_web/lib/block_scout_web/templates/tokens/overview/_details.html.eex
  37. 8
      apps/block_scout_web/lib/block_scout_web/templates/tokens/overview/_tabs.html.eex
  38. 8
      apps/block_scout_web/lib/block_scout_web/templates/transaction/_tabs.html.eex
  39. 58
      apps/block_scout_web/lib/block_scout_web/views/access_helpers.ex
  40. 1
      apps/block_scout_web/lib/block_scout_web/views/address_coin_balance_view.ex
  41. 2
      apps/block_scout_web/lib/block_scout_web/views/address_internal_transaction_view.ex
  42. 2
      apps/block_scout_web/lib/block_scout_web/views/address_token_transfer_view.ex
  43. 1
      apps/block_scout_web/lib/block_scout_web/views/address_transaction_view.ex
  44. 2
      apps/block_scout_web/lib/block_scout_web/views/address_view.ex
  45. 2
      apps/block_scout_web/lib/block_scout_web/views/tokens/overview_view.ex
  46. 1
      apps/block_scout_web/lib/block_scout_web/views/transaction_internal_transaction_view.ex
  47. 2
      apps/block_scout_web/lib/block_scout_web/views/transaction_view.ex
  48. 38
      apps/block_scout_web/priv/gettext/default.pot
  49. 38
      apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po

@ -1,6 +1,7 @@
## Current ## Current
### Features ### Features
- [#3311](https://github.com/poanetwork/blockscout/pull/3311) - List of addresses with restricted access option
- [#3293](https://github.com/poanetwork/blockscout/pull/3293) - Composite market cap for xDai: TokenBridge + OmniBridge - [#3293](https://github.com/poanetwork/blockscout/pull/3293) - Composite market cap for xDai: TokenBridge + OmniBridge
- [#3282](https://github.com/poanetwork/blockscout/pull/3282) - Import bridged tokens custom metadata - [#3282](https://github.com/poanetwork/blockscout/pull/3282) - Import bridged tokens custom metadata
- [#3281](https://github.com/poanetwork/blockscout/pull/3281) - Write contract: display currently connected address - [#3281](https://github.com/poanetwork/blockscout/pull/3281) - Write contract: display currently connected address

@ -37,7 +37,9 @@ config :block_scout_web,
external_apps: System.get_env("EXTERNAL_APPS"), external_apps: System.get_env("EXTERNAL_APPS"),
multi_token_bridge_mediator: System.get_env("MULTI_TOKEN_BRIDGE_MEDIATOR"), multi_token_bridge_mediator: System.get_env("MULTI_TOKEN_BRIDGE_MEDIATOR"),
foreign_json_rpc: System.get_env("FOREIGN_JSON_RPC"), foreign_json_rpc: System.get_env("FOREIGN_JSON_RPC"),
gas_price: System.get_env("GAS_PRICE", nil) gas_price: System.get_env("GAS_PRICE", nil),
restricted_list: System.get_env("RESTRICTED_LIST", nil),
restricted_list_key: System.get_env("RESTRICTED_LIST_KEY", nil)
config :block_scout_web, BlockScoutWeb.Counters.BlocksIndexedCounter, enabled: true config :block_scout_web, BlockScoutWeb.Counters.BlocksIndexedCounter, enabled: true

@ -39,7 +39,7 @@ defmodule BlockScoutWeb.AddressChannel do
{:ok, address = %{fetched_coin_balance: balance}} when not is_nil(balance) <- {:ok, address = %{fetched_coin_balance: balance}} when not is_nil(balance) <-
Chain.hash_to_address(casted_address_hash), Chain.hash_to_address(casted_address_hash),
exchange_rate <- Market.get_exchange_rate(Explorer.coin()) || Token.null(), exchange_rate <- Market.get_exchange_rate(Explorer.coin()) || Token.null(),
{:ok, rendered} <- render_balance_card(address, exchange_rate, socket.assigns.locale) do {:ok, rendered} <- render_balance_card(address, exchange_rate, socket) do
reply = reply =
{:ok, {:ok,
%{ %{
@ -60,7 +60,7 @@ defmodule BlockScoutWeb.AddressChannel do
%{address: address, exchange_rate: exchange_rate}, %{address: address, exchange_rate: exchange_rate},
socket socket
) do ) do
case render_balance_card(address, exchange_rate, socket.assigns.locale) do case render_balance_card(address, exchange_rate, socket) do
{:ok, rendered} -> {:ok, rendered} ->
push(socket, "balance", %{ push(socket, "balance", %{
balance_card: rendered, balance_card: rendered,
@ -190,14 +190,15 @@ defmodule BlockScoutWeb.AddressChannel do
{:noreply, socket} {:noreply, socket}
end end
defp render_balance_card(address, exchange_rate, locale) do defp render_balance_card(address, exchange_rate, socket) do
Gettext.put_locale(BlockScoutWeb.Gettext, locale) Gettext.put_locale(BlockScoutWeb.Gettext, socket.assigns.locale)
try do try do
rendered = rendered =
View.render_to_string( View.render_to_string(
AddressView, AddressView,
"_balance_card.html", "_balance_card.html",
conn: socket,
address: address, address: address,
coin_balance_status: :current, coin_balance_status: :current,
exchange_rate: exchange_rate exchange_rate: exchange_rate

@ -5,10 +5,12 @@ defmodule BlockScoutWeb.AddressCoinBalanceByDayController do
use BlockScoutWeb, :controller use BlockScoutWeb, :controller
alias BlockScoutWeb.AccessHelpers
alias Explorer.Chain alias Explorer.Chain
def index(conn, %{"address_id" => address_hash_string, "type" => "JSON"}) do def index(conn, %{"address_id" => address_hash_string, "type" => "JSON"} = params) do
with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string) do with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string),
{:ok, false} <- AccessHelpers.restricted_access?(address_hash_string, params) do
balances_by_day = balances_by_day =
address_hash address_hash
|> Chain.address_to_balances_by_day() |> Chain.address_to_balances_by_day()
@ -17,6 +19,9 @@ defmodule BlockScoutWeb.AddressCoinBalanceByDayController do
end) end)
json(conn, balances_by_day) json(conn, balances_by_day)
else
_ ->
not_found(conn)
end end
end end
end end

@ -7,7 +7,7 @@ defmodule BlockScoutWeb.AddressCoinBalanceController do
import BlockScoutWeb.Chain, only: [paging_options: 1, next_page_params: 3, split_list_by_page: 1] import BlockScoutWeb.Chain, only: [paging_options: 1, next_page_params: 3, split_list_by_page: 1]
alias BlockScoutWeb.AddressCoinBalanceView alias BlockScoutWeb.{AccessHelpers, AddressCoinBalanceView}
alias Explorer.{Chain, Market} alias Explorer.{Chain, Market}
alias Explorer.Chain.Address alias Explorer.Chain.Address
alias Explorer.ExchangeRates.Token alias Explorer.ExchangeRates.Token
@ -16,7 +16,8 @@ defmodule BlockScoutWeb.AddressCoinBalanceController do
def index(conn, %{"address_id" => address_hash_string, "type" => "JSON"} = params) do def index(conn, %{"address_id" => address_hash_string, "type" => "JSON"} = params) do
with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string), with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string),
:ok <- Chain.check_address_exists(address_hash) do :ok <- Chain.check_address_exists(address_hash),
{:ok, false} <- AccessHelpers.restricted_access?(address_hash_string, params) do
full_options = paging_options(params) full_options = paging_options(params)
coin_balances_plus_one = Chain.address_to_coin_balances(address_hash, full_options) coin_balances_plus_one = Chain.address_to_coin_balances(address_hash, full_options)
@ -49,6 +50,9 @@ defmodule BlockScoutWeb.AddressCoinBalanceController do
json(conn, %{items: coin_balances_json, next_page_path: next_page_url}) json(conn, %{items: coin_balances_json, next_page_path: next_page_url})
else else
{:restricted_access, _} ->
not_found(conn)
:error -> :error ->
unprocessable_entity(conn) unprocessable_entity(conn)
@ -57,9 +61,10 @@ defmodule BlockScoutWeb.AddressCoinBalanceController do
end end
end end
def index(conn, %{"address_id" => address_hash_string}) do def index(conn, %{"address_id" => address_hash_string} = params) do
with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string), with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string),
{:ok, address} <- Chain.hash_to_address(address_hash) do {:ok, address} <- Chain.hash_to_address(address_hash),
{:ok, false} <- AccessHelpers.restricted_access?(address_hash_string, params) do
render(conn, "index.html", render(conn, "index.html",
address: address, address: address,
coin_balance_status: CoinBalanceOnDemand.trigger_fetch(address), coin_balance_status: CoinBalanceOnDemand.trigger_fetch(address),
@ -68,6 +73,9 @@ defmodule BlockScoutWeb.AddressCoinBalanceController do
counters_path: address_path(conn, :address_counters, %{"id" => Address.checksum(address_hash)}) counters_path: address_path(conn, :address_counters, %{"id" => Address.checksum(address_hash)})
) )
else else
{:restricted_access, _} ->
not_found(conn)
:error -> :error ->
unprocessable_entity(conn) unprocessable_entity(conn)

@ -2,11 +2,12 @@
defmodule BlockScoutWeb.AddressContractController do defmodule BlockScoutWeb.AddressContractController do
use BlockScoutWeb, :controller use BlockScoutWeb, :controller
alias BlockScoutWeb.AccessHelpers
alias Explorer.{Chain, Market} alias Explorer.{Chain, Market}
alias Explorer.ExchangeRates.Token alias Explorer.ExchangeRates.Token
alias Indexer.Fetcher.CoinBalanceOnDemand alias Indexer.Fetcher.CoinBalanceOnDemand
def index(conn, %{"address_id" => address_hash_string}) do def index(conn, %{"address_id" => address_hash_string} = params) do
address_options = [ address_options = [
necessity_by_association: %{ necessity_by_association: %{
:contracts_creation_internal_transaction => :optional, :contracts_creation_internal_transaction => :optional,
@ -18,7 +19,8 @@ defmodule BlockScoutWeb.AddressContractController do
] ]
with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string), with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string),
{:ok, address} <- Chain.find_contract_address(address_hash, address_options, true) do {:ok, address} <- Chain.find_contract_address(address_hash, address_options, true),
{:ok, false} <- AccessHelpers.restricted_access?(address_hash_string, params) do
render( render(
conn, conn,
"index.html", "index.html",
@ -28,6 +30,9 @@ defmodule BlockScoutWeb.AddressContractController do
counters_path: address_path(conn, :address_counters, %{"id" => address_hash_string}) counters_path: address_path(conn, :address_counters, %{"id" => address_hash_string})
) )
else else
{:restricted_access, _} ->
not_found(conn)
:error -> :error ->
not_found(conn) not_found(conn)

@ -3,7 +3,7 @@ defmodule BlockScoutWeb.AddressController do
import BlockScoutWeb.Chain, only: [paging_options: 1, next_page_params: 3, split_list_by_page: 1] import BlockScoutWeb.Chain, only: [paging_options: 1, next_page_params: 3, split_list_by_page: 1]
alias BlockScoutWeb.AddressView alias BlockScoutWeb.{AccessHelpers, AddressView}
alias Explorer.{Chain, Market} alias Explorer.{Chain, Market}
alias Explorer.ExchangeRates.Token alias Explorer.ExchangeRates.Token
alias Phoenix.View alias Phoenix.View
@ -67,7 +67,7 @@ defmodule BlockScoutWeb.AddressController do
end end
def show(conn, %{"id" => id}) do def show(conn, %{"id" => id}) do
redirect(conn, to: address_transaction_path(conn, :index, id)) redirect(conn, to: AccessHelpers.get_path(conn, :address_transaction_path, :index, id))
end end
def address_counters(conn, %{"id" => address_hash_string}) do def address_counters(conn, %{"id" => address_hash_string}) do

@ -1,13 +1,15 @@
defmodule BlockScoutWeb.AddressDecompiledContractController do defmodule BlockScoutWeb.AddressDecompiledContractController do
use BlockScoutWeb, :controller use BlockScoutWeb, :controller
alias BlockScoutWeb.AccessHelpers
alias Explorer.{Chain, Market} alias Explorer.{Chain, Market}
alias Explorer.ExchangeRates.Token alias Explorer.ExchangeRates.Token
alias Indexer.Fetcher.CoinBalanceOnDemand alias Indexer.Fetcher.CoinBalanceOnDemand
def index(conn, %{"address_id" => address_hash_string}) do def index(conn, %{"address_id" => address_hash_string} = params) do
with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string), with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string),
{:ok, address} <- Chain.find_decompiled_contract_address(address_hash) do {:ok, address} <- Chain.find_decompiled_contract_address(address_hash),
{:ok, false} <- AccessHelpers.restricted_access?(address_hash_string, params) do
render( render(
conn, conn,
"index.html", "index.html",
@ -17,6 +19,9 @@ defmodule BlockScoutWeb.AddressDecompiledContractController do
counters_path: address_path(conn, :address_counters, %{"id" => address_hash_string}) counters_path: address_path(conn, :address_counters, %{"id" => address_hash_string})
) )
else else
{:restricted_access, _} ->
not_found(conn)
:error -> :error ->
not_found(conn) not_found(conn)

@ -7,7 +7,7 @@ defmodule BlockScoutWeb.AddressInternalTransactionController do
import BlockScoutWeb.Chain, only: [current_filter: 1, paging_options: 1, next_page_params: 3, split_list_by_page: 1] import BlockScoutWeb.Chain, only: [current_filter: 1, paging_options: 1, next_page_params: 3, split_list_by_page: 1]
alias BlockScoutWeb.InternalTransactionView alias BlockScoutWeb.{AccessHelpers, InternalTransactionView}
alias Explorer.{Chain, Market} alias Explorer.{Chain, Market}
alias Explorer.ExchangeRates.Token alias Explorer.ExchangeRates.Token
alias Indexer.Fetcher.CoinBalanceOnDemand alias Indexer.Fetcher.CoinBalanceOnDemand
@ -15,7 +15,8 @@ defmodule BlockScoutWeb.AddressInternalTransactionController do
def index(conn, %{"address_id" => address_hash_string, "type" => "JSON"} = params) do def index(conn, %{"address_id" => address_hash_string, "type" => "JSON"} = params) do
with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string), with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string),
{:ok, address} <- Chain.hash_to_address(address_hash, [], false) do {:ok, address} <- Chain.hash_to_address(address_hash, [], false),
{:ok, false} <- AccessHelpers.restricted_access?(address_hash_string, params) do
full_options = full_options =
[ [
necessity_by_association: %{ necessity_by_association: %{
@ -51,6 +52,9 @@ defmodule BlockScoutWeb.AddressInternalTransactionController do
json(conn, %{items: internal_transactions_json, next_page_path: next_page_path}) json(conn, %{items: internal_transactions_json, next_page_path: next_page_path})
else else
{:restricted_access, _} ->
not_found(conn)
:error -> :error ->
not_found(conn) not_found(conn)
@ -61,7 +65,8 @@ defmodule BlockScoutWeb.AddressInternalTransactionController do
def index(conn, %{"address_id" => address_hash_string} = params) do def index(conn, %{"address_id" => address_hash_string} = params) do
with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string), with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string),
{:ok, address} <- Chain.hash_to_address(address_hash) do {:ok, address} <- Chain.hash_to_address(address_hash),
{:ok, false} <- AccessHelpers.restricted_access?(address_hash_string, params) do
render( render(
conn, conn,
"index.html", "index.html",
@ -73,6 +78,9 @@ defmodule BlockScoutWeb.AddressInternalTransactionController do
counters_path: address_path(conn, :address_counters, %{"id" => address_hash_string}) counters_path: address_path(conn, :address_counters, %{"id" => address_hash_string})
) )
else else
{:restricted_access, _} ->
not_found(conn)
:error -> :error ->
not_found(conn) not_found(conn)

@ -5,7 +5,7 @@ defmodule BlockScoutWeb.AddressLogsController do
import BlockScoutWeb.Chain, only: [paging_options: 1, next_page_params: 3, split_list_by_page: 1] import BlockScoutWeb.Chain, only: [paging_options: 1, next_page_params: 3, split_list_by_page: 1]
alias BlockScoutWeb.AddressLogsView alias BlockScoutWeb.{AccessHelpers, AddressLogsView}
alias Explorer.{Chain, Market} alias Explorer.{Chain, Market}
alias Explorer.ExchangeRates.Token alias Explorer.ExchangeRates.Token
alias Indexer.Fetcher.CoinBalanceOnDemand alias Indexer.Fetcher.CoinBalanceOnDemand
@ -15,7 +15,8 @@ defmodule BlockScoutWeb.AddressLogsController do
def index(conn, %{"address_id" => address_hash_string, "type" => "JSON"} = params) do def index(conn, %{"address_id" => address_hash_string, "type" => "JSON"} = params) do
with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string), with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string),
:ok <- Chain.check_address_exists(address_hash) do :ok <- Chain.check_address_exists(address_hash),
{:ok, false} <- AccessHelpers.restricted_access?(address_hash_string, params) do
logs_plus_one = Chain.address_to_logs(address_hash, paging_options(params)) logs_plus_one = Chain.address_to_logs(address_hash, paging_options(params))
{results, next_page} = split_list_by_page(logs_plus_one) {results, next_page} = split_list_by_page(logs_plus_one)
@ -52,9 +53,10 @@ defmodule BlockScoutWeb.AddressLogsController do
end end
end end
def index(conn, %{"address_id" => address_hash_string}) do def index(conn, %{"address_id" => address_hash_string} = params) do
with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string), with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string),
{:ok, address} <- Chain.hash_to_address(address_hash) do {:ok, address} <- Chain.hash_to_address(address_hash),
{:ok, false} <- AccessHelpers.restricted_access?(address_hash_string, params) do
render( render(
conn, conn,
"index.html", "index.html",

@ -8,12 +8,13 @@
defmodule BlockScoutWeb.AddressReadContractController do defmodule BlockScoutWeb.AddressReadContractController do
use BlockScoutWeb, :controller use BlockScoutWeb, :controller
alias BlockScoutWeb.AccessHelpers
alias Explorer.{Chain, Market} alias Explorer.{Chain, Market}
alias Explorer.Chain.Address alias Explorer.Chain.Address
alias Explorer.ExchangeRates.Token alias Explorer.ExchangeRates.Token
alias Indexer.Fetcher.CoinBalanceOnDemand alias Indexer.Fetcher.CoinBalanceOnDemand
def index(conn, %{"address_id" => address_hash_string}) do def index(conn, %{"address_id" => address_hash_string} = params) do
address_options = [ address_options = [
necessity_by_association: %{ necessity_by_association: %{
:contracts_creation_internal_transaction => :optional, :contracts_creation_internal_transaction => :optional,
@ -26,7 +27,8 @@ defmodule BlockScoutWeb.AddressReadContractController do
with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string), with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string),
{:ok, address} <- Chain.find_contract_address(address_hash, address_options, true), {:ok, address} <- Chain.find_contract_address(address_hash, address_options, true),
false <- is_nil(address.smart_contract) do false <- is_nil(address.smart_contract),
{:ok, false} <- AccessHelpers.restricted_access?(address_hash_string, params) do
render( render(
conn, conn,
"index.html", "index.html",

@ -2,12 +2,13 @@
defmodule BlockScoutWeb.AddressReadProxyController do defmodule BlockScoutWeb.AddressReadProxyController do
use BlockScoutWeb, :controller use BlockScoutWeb, :controller
alias BlockScoutWeb.AccessHelpers
alias Explorer.{Chain, Market} alias Explorer.{Chain, Market}
alias Explorer.Chain.Address alias Explorer.Chain.Address
alias Explorer.ExchangeRates.Token alias Explorer.ExchangeRates.Token
alias Indexer.Fetcher.CoinBalanceOnDemand alias Indexer.Fetcher.CoinBalanceOnDemand
def index(conn, %{"address_id" => address_hash_string}) do def index(conn, %{"address_id" => address_hash_string} = params) do
address_options = [ address_options = [
necessity_by_association: %{ necessity_by_association: %{
:contracts_creation_internal_transaction => :optional, :contracts_creation_internal_transaction => :optional,
@ -20,7 +21,8 @@ defmodule BlockScoutWeb.AddressReadProxyController do
with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string), with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string),
{:ok, address} <- Chain.find_contract_address(address_hash, address_options, true), {:ok, address} <- Chain.find_contract_address(address_hash, address_options, true),
false <- is_nil(address.smart_contract) do false <- is_nil(address.smart_contract),
{:ok, false} <- AccessHelpers.restricted_access?(address_hash_string, params) do
render( render(
conn, conn,
"index.html", "index.html",

@ -1,11 +1,13 @@
defmodule BlockScoutWeb.AddressTokenBalanceController do defmodule BlockScoutWeb.AddressTokenBalanceController do
use BlockScoutWeb, :controller use BlockScoutWeb, :controller
alias BlockScoutWeb.AccessHelpers
alias Explorer.{Chain, Market} alias Explorer.{Chain, Market}
def index(conn, %{"address_id" => address_hash_string}) do def index(conn, %{"address_id" => address_hash_string} = params) do
with true <- ajax?(conn), with true <- ajax?(conn),
{:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string) do {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string),
{:ok, false} <- AccessHelpers.restricted_access?(address_hash_string, params) do
token_balances = token_balances =
address_hash address_hash
|> Chain.fetch_last_token_balances() |> Chain.fetch_last_token_balances()

@ -3,7 +3,7 @@ defmodule BlockScoutWeb.AddressTokenController do
import BlockScoutWeb.Chain, only: [next_page_params: 3, paging_options: 1, split_list_by_page: 1] import BlockScoutWeb.Chain, only: [next_page_params: 3, paging_options: 1, split_list_by_page: 1]
alias BlockScoutWeb.AddressTokenView alias BlockScoutWeb.{AccessHelpers, AddressTokenView}
alias Explorer.{Chain, Market} alias Explorer.{Chain, Market}
alias Explorer.Chain.Address alias Explorer.Chain.Address
alias Explorer.ExchangeRates.Token alias Explorer.ExchangeRates.Token
@ -12,7 +12,8 @@ defmodule BlockScoutWeb.AddressTokenController do
def index(conn, %{"address_id" => address_hash_string, "type" => "JSON"} = params) do def index(conn, %{"address_id" => address_hash_string, "type" => "JSON"} = params) do
with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string), with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string),
{:ok, address} <- Chain.hash_to_address(address_hash, [], false) do {:ok, address} <- Chain.hash_to_address(address_hash, [], false),
{:ok, false} <- AccessHelpers.restricted_access?(address_hash_string, params) do
tokens_plus_one = Chain.address_tokens_with_balance(address_hash, paging_options(params)) tokens_plus_one = Chain.address_tokens_with_balance(address_hash, paging_options(params))
{tokens, next_page} = split_list_by_page(tokens_plus_one) {tokens, next_page} = split_list_by_page(tokens_plus_one)
@ -46,6 +47,9 @@ defmodule BlockScoutWeb.AddressTokenController do
} }
) )
else else
{:restricted_access, _} ->
not_found(conn)
:error -> :error ->
unprocessable_entity(conn) unprocessable_entity(conn)
@ -54,9 +58,10 @@ defmodule BlockScoutWeb.AddressTokenController do
end end
end end
def index(conn, %{"address_id" => address_hash_string} = _params) do def index(conn, %{"address_id" => address_hash_string} = params) do
with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string), with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string),
{:ok, address} <- Chain.hash_to_address(address_hash) do {:ok, address} <- Chain.hash_to_address(address_hash),
{:ok, false} <- AccessHelpers.restricted_access?(address_hash_string, params) do
render( render(
conn, conn,
"index.html", "index.html",
@ -67,6 +72,9 @@ defmodule BlockScoutWeb.AddressTokenController do
counters_path: address_path(conn, :address_counters, %{"id" => Address.checksum(address_hash)}) counters_path: address_path(conn, :address_counters, %{"id" => Address.checksum(address_hash)})
) )
else else
{:restricted_access, _} ->
not_found(conn)
:error -> :error ->
unprocessable_entity(conn) unprocessable_entity(conn)

@ -1,7 +1,7 @@
defmodule BlockScoutWeb.AddressTokenTransferController do defmodule BlockScoutWeb.AddressTokenTransferController do
use BlockScoutWeb, :controller use BlockScoutWeb, :controller
alias BlockScoutWeb.TransactionView alias BlockScoutWeb.{AccessHelpers, TransactionView}
alias Explorer.ExchangeRates.Token alias Explorer.ExchangeRates.Token
alias Explorer.{Chain, Market} alias Explorer.{Chain, Market}
alias Explorer.Chain.Address alias Explorer.Chain.Address
@ -38,7 +38,8 @@ defmodule BlockScoutWeb.AddressTokenTransferController do
with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string), with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string),
{:ok, token_hash} <- Chain.string_to_address_hash(token_hash_string), {:ok, token_hash} <- Chain.string_to_address_hash(token_hash_string),
{:ok, address} <- Chain.hash_to_address(address_hash), {:ok, address} <- Chain.hash_to_address(address_hash),
{:ok, _} <- Chain.token_from_address_hash(token_hash) do {:ok, _} <- Chain.token_from_address_hash(token_hash),
{:ok, false} <- AccessHelpers.restricted_access?(address_hash_string, params) do
transactions = transactions =
Chain.address_to_transactions_with_token_transfers( Chain.address_to_transactions_with_token_transfers(
address_hash, address_hash,
@ -77,6 +78,9 @@ defmodule BlockScoutWeb.AddressTokenTransferController do
json(conn, %{items: transfers_json, next_page_path: next_page_path}) json(conn, %{items: transfers_json, next_page_path: next_page_path})
else else
{:restricted_access, _} ->
not_found(conn)
:error -> :error ->
unprocessable_entity(conn) unprocessable_entity(conn)
@ -87,12 +91,13 @@ defmodule BlockScoutWeb.AddressTokenTransferController do
def index( def index(
conn, conn,
%{"address_id" => address_hash_string, "address_token_id" => token_hash_string} %{"address_id" => address_hash_string, "address_token_id" => token_hash_string} = params
) do ) do
with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string), with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string),
{:ok, token_hash} <- Chain.string_to_address_hash(token_hash_string), {:ok, token_hash} <- Chain.string_to_address_hash(token_hash_string),
{:ok, address} <- Chain.hash_to_address(address_hash), {:ok, address} <- Chain.hash_to_address(address_hash),
{:ok, token} <- Chain.token_from_address_hash(token_hash) do {:ok, token} <- Chain.token_from_address_hash(token_hash),
{:ok, false} <- AccessHelpers.restricted_access?(address_hash_string, params) do
render( render(
conn, conn,
"index.html", "index.html",
@ -104,6 +109,9 @@ defmodule BlockScoutWeb.AddressTokenTransferController do
counters_path: address_path(conn, :address_counters, %{"id" => Address.checksum(address_hash)}) counters_path: address_path(conn, :address_counters, %{"id" => Address.checksum(address_hash)})
) )
else else
{:restricted_access, _} ->
not_found(conn)
:error -> :error ->
unprocessable_entity(conn) unprocessable_entity(conn)
@ -120,7 +128,8 @@ defmodule BlockScoutWeb.AddressTokenTransferController do
} = params } = params
) do ) do
with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string), with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string),
{:ok, address} <- Chain.hash_to_address(address_hash) do {:ok, address} <- Chain.hash_to_address(address_hash),
{:ok, false} <- AccessHelpers.restricted_access?(address_hash_string, params) do
options = options =
@transaction_necessity_by_association @transaction_necessity_by_association
|> Keyword.merge(paging_options(params)) |> Keyword.merge(paging_options(params))
@ -162,6 +171,9 @@ defmodule BlockScoutWeb.AddressTokenTransferController do
json(conn, %{items: transfers_json, next_page_path: next_page_path}) json(conn, %{items: transfers_json, next_page_path: next_page_path})
else else
{:restricted_access, _} ->
not_found(conn)
:error -> :error ->
unprocessable_entity(conn) unprocessable_entity(conn)
@ -175,7 +187,8 @@ defmodule BlockScoutWeb.AddressTokenTransferController do
%{"address_id" => address_hash_string} = params %{"address_id" => address_hash_string} = params
) do ) do
with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string), with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string),
{:ok, address} <- Chain.hash_to_address(address_hash) do {:ok, address} <- Chain.hash_to_address(address_hash),
{:ok, false} <- AccessHelpers.restricted_access?(address_hash_string, params) do
render( render(
conn, conn,
"index.html", "index.html",
@ -187,6 +200,9 @@ defmodule BlockScoutWeb.AddressTokenTransferController do
counters_path: address_path(conn, :address_counters, %{"id" => Address.checksum(address_hash)}) counters_path: address_path(conn, :address_counters, %{"id" => Address.checksum(address_hash)})
) )
else else
{:restricted_access, _} ->
not_found(conn)
:error -> :error ->
unprocessable_entity(conn) unprocessable_entity(conn)

@ -7,7 +7,7 @@ defmodule BlockScoutWeb.AddressTransactionController do
import BlockScoutWeb.Chain, only: [current_filter: 1, paging_options: 1, next_page_params: 3, split_list_by_page: 1] import BlockScoutWeb.Chain, only: [current_filter: 1, paging_options: 1, next_page_params: 3, split_list_by_page: 1]
alias BlockScoutWeb.TransactionView alias BlockScoutWeb.{AccessHelpers, TransactionView}
alias Explorer.{Chain, Market} alias Explorer.{Chain, Market}
alias Explorer.Chain.{AddressTokenTransferCsvExporter, AddressTransactionCsvExporter} alias Explorer.Chain.{AddressTokenTransferCsvExporter, AddressTransactionCsvExporter}
alias Explorer.ExchangeRates.Token alias Explorer.ExchangeRates.Token
@ -30,7 +30,8 @@ defmodule BlockScoutWeb.AddressTransactionController do
address_options = [necessity_by_association: %{:names => :optional}] address_options = [necessity_by_association: %{:names => :optional}]
with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string), with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string),
{:ok, address} <- Chain.hash_to_address(address_hash, address_options, false) do {:ok, address} <- Chain.hash_to_address(address_hash, address_options, false),
{:ok, false} <- AccessHelpers.restricted_access?(address_hash_string, params) do
options = options =
@transaction_necessity_by_association @transaction_necessity_by_association
|> Keyword.merge(paging_options(params)) |> Keyword.merge(paging_options(params))
@ -82,6 +83,9 @@ defmodule BlockScoutWeb.AddressTransactionController do
:error -> :error ->
unprocessable_entity(conn) unprocessable_entity(conn)
{:restricted_access, _} ->
not_found(conn)
{:error, :not_found} -> {:error, :not_found} ->
case Chain.Hash.Address.validate(address_hash_string) do case Chain.Hash.Address.validate(address_hash_string) do
{:ok, _} -> {:ok, _} ->
@ -95,7 +99,8 @@ defmodule BlockScoutWeb.AddressTransactionController do
def index(conn, %{"address_id" => address_hash_string} = params) do def index(conn, %{"address_id" => address_hash_string} = params) do
with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string), with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string),
{:ok, address} <- Chain.hash_to_address(address_hash) do {:ok, address} <- Chain.hash_to_address(address_hash),
{:ok, false} <- AccessHelpers.restricted_access?(address_hash_string, params) do
render( render(
conn, conn,
"index.html", "index.html",
@ -110,6 +115,9 @@ defmodule BlockScoutWeb.AddressTransactionController do
:error -> :error ->
unprocessable_entity(conn) unprocessable_entity(conn)
{:restricted_access, _} ->
not_found(conn)
{:error, :not_found} -> {:error, :not_found} ->
{:ok, address_hash} = Chain.string_to_address_hash(address_hash_string) {:ok, address_hash} = Chain.string_to_address_hash(address_hash_string)
address = %Chain.Address{hash: address_hash, smart_contract: nil, token: nil} address = %Chain.Address{hash: address_hash, smart_contract: nil, token: nil}

@ -7,7 +7,7 @@ defmodule BlockScoutWeb.AddressValidationController do
import BlockScoutWeb.Chain, import BlockScoutWeb.Chain,
only: [paging_options: 1, next_page_params: 3, split_list_by_page: 1] only: [paging_options: 1, next_page_params: 3, split_list_by_page: 1]
alias BlockScoutWeb.BlockView alias BlockScoutWeb.{AccessHelpers, BlockView}
alias Explorer.ExchangeRates.Token alias Explorer.ExchangeRates.Token
alias Explorer.{Chain, Market} alias Explorer.{Chain, Market}
alias Indexer.Fetcher.CoinBalanceOnDemand alias Indexer.Fetcher.CoinBalanceOnDemand
@ -15,7 +15,8 @@ defmodule BlockScoutWeb.AddressValidationController do
def index(conn, %{"address_id" => address_hash_string, "type" => "JSON"} = params) do def index(conn, %{"address_id" => address_hash_string, "type" => "JSON"} = params) do
with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string), with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string),
{:ok, _} <- Chain.find_or_insert_address_from_hash(address_hash, [], false) do {:ok, _} <- Chain.find_or_insert_address_from_hash(address_hash, [], false),
{:ok, false} <- AccessHelpers.restricted_access?(address_hash_string, params) do
full_options = full_options =
Keyword.merge( Keyword.merge(
[ [
@ -59,14 +60,18 @@ defmodule BlockScoutWeb.AddressValidationController do
json(conn, %{items: items, next_page_path: next_page_path}) json(conn, %{items: items, next_page_path: next_page_path})
else else
{:restricted_access, _} ->
not_found(conn)
:error -> :error ->
unprocessable_entity(conn) unprocessable_entity(conn)
end end
end end
def index(conn, %{"address_id" => address_hash_string}) do def index(conn, %{"address_id" => address_hash_string} = params) do
with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string), with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string),
{:ok, address} <- Chain.find_or_insert_address_from_hash(address_hash) do {:ok, address} <- Chain.find_or_insert_address_from_hash(address_hash),
{:ok, false} <- AccessHelpers.restricted_access?(address_hash_string, params) do
render( render(
conn, conn,
"index.html", "index.html",
@ -77,6 +82,9 @@ defmodule BlockScoutWeb.AddressValidationController do
exchange_rate: Market.get_exchange_rate(Explorer.coin()) || Token.null() exchange_rate: Market.get_exchange_rate(Explorer.coin()) || Token.null()
) )
else else
{:restricted_access, _} ->
not_found(conn)
:error -> :error ->
unprocessable_entity(conn) unprocessable_entity(conn)

@ -8,12 +8,13 @@
defmodule BlockScoutWeb.AddressWriteContractController do defmodule BlockScoutWeb.AddressWriteContractController do
use BlockScoutWeb, :controller use BlockScoutWeb, :controller
alias BlockScoutWeb.AccessHelpers
alias Explorer.{Chain, Market} alias Explorer.{Chain, Market}
alias Explorer.Chain.Address alias Explorer.Chain.Address
alias Explorer.ExchangeRates.Token alias Explorer.ExchangeRates.Token
alias Indexer.Fetcher.CoinBalanceOnDemand alias Indexer.Fetcher.CoinBalanceOnDemand
def index(conn, %{"address_id" => address_hash_string}) do def index(conn, %{"address_id" => address_hash_string} = params) do
address_options = [ address_options = [
necessity_by_association: %{ necessity_by_association: %{
:contracts_creation_internal_transaction => :optional, :contracts_creation_internal_transaction => :optional,
@ -26,7 +27,8 @@ defmodule BlockScoutWeb.AddressWriteContractController do
with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string), with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string),
{:ok, address} <- Chain.find_contract_address(address_hash, address_options, true), {:ok, address} <- Chain.find_contract_address(address_hash, address_options, true),
false <- is_nil(address.smart_contract) do false <- is_nil(address.smart_contract),
{:ok, false} <- AccessHelpers.restricted_access?(address_hash_string, params) do
render( render(
conn, conn,
"index.html", "index.html",

@ -2,12 +2,13 @@
defmodule BlockScoutWeb.AddressWriteProxyController do defmodule BlockScoutWeb.AddressWriteProxyController do
use BlockScoutWeb, :controller use BlockScoutWeb, :controller
alias BlockScoutWeb.AccessHelpers
alias Explorer.{Chain, Market} alias Explorer.{Chain, Market}
alias Explorer.Chain.Address alias Explorer.Chain.Address
alias Explorer.ExchangeRates.Token alias Explorer.ExchangeRates.Token
alias Indexer.Fetcher.CoinBalanceOnDemand alias Indexer.Fetcher.CoinBalanceOnDemand
def index(conn, %{"address_id" => address_hash_string}) do def index(conn, %{"address_id" => address_hash_string} = params) do
address_options = [ address_options = [
necessity_by_association: %{ necessity_by_association: %{
:contracts_creation_internal_transaction => :optional, :contracts_creation_internal_transaction => :optional,
@ -20,7 +21,8 @@ defmodule BlockScoutWeb.AddressWriteProxyController do
with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string), with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string),
{:ok, address} <- Chain.find_contract_address(address_hash, address_options, true), {:ok, address} <- Chain.find_contract_address(address_hash, address_options, true),
false <- is_nil(address.smart_contract) do false <- is_nil(address.smart_contract),
{:ok, false} <- AccessHelpers.restricted_access?(address_hash_string, params) do
render( render(
conn, conn,
"index.html", "index.html",

@ -1,6 +1,7 @@
defmodule BlockScoutWeb.Tokens.HolderController do defmodule BlockScoutWeb.Tokens.HolderController do
use BlockScoutWeb, :controller use BlockScoutWeb, :controller
alias BlockScoutWeb.AccessHelpers
alias BlockScoutWeb.Tokens.HolderView alias BlockScoutWeb.Tokens.HolderView
alias Explorer.{Chain, Market} alias Explorer.{Chain, Market}
alias Explorer.Chain.Address alias Explorer.Chain.Address
@ -16,7 +17,8 @@ defmodule BlockScoutWeb.Tokens.HolderController do
def index(conn, %{"token_id" => address_hash_string, "type" => "JSON"} = params) do def index(conn, %{"token_id" => address_hash_string, "type" => "JSON"} = params) do
with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string), with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string),
{:ok, token} <- Chain.token_from_address_hash(address_hash), {:ok, token} <- Chain.token_from_address_hash(address_hash),
token_balances <- Chain.fetch_token_holders_from_token_hash(address_hash, paging_options(params)) do token_balances <- Chain.fetch_token_holders_from_token_hash(address_hash, paging_options(params)),
{:ok, false} <- AccessHelpers.restricted_access?(address_hash_string, params) do
{token_balances_paginated, next_page} = split_list_by_page(token_balances) {token_balances_paginated, next_page} = split_list_by_page(token_balances)
next_page_path = next_page_path =
@ -35,6 +37,9 @@ defmodule BlockScoutWeb.Tokens.HolderController do
json(conn, %{items: token_balances_json, next_page_path: next_page_path}) json(conn, %{items: token_balances_json, next_page_path: next_page_path})
else else
{:restricted_access, _} ->
not_found(conn)
:error -> :error ->
not_found(conn) not_found(conn)
@ -43,11 +48,12 @@ defmodule BlockScoutWeb.Tokens.HolderController do
end end
end end
def index(conn, %{"token_id" => address_hash_string}) do def index(conn, %{"token_id" => address_hash_string} = params) do
options = [necessity_by_association: %{[contract_address: :smart_contract] => :optional}] options = [necessity_by_association: %{[contract_address: :smart_contract] => :optional}]
with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string), with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string),
{:ok, token} <- Chain.token_from_address_hash(address_hash, options) do {:ok, token} <- Chain.token_from_address_hash(address_hash, options),
{:ok, false} <- AccessHelpers.restricted_access?(address_hash_string, params) do
render( render(
conn, conn,
"index.html", "index.html",
@ -56,6 +62,9 @@ defmodule BlockScoutWeb.Tokens.HolderController do
counters_path: token_path(conn, :token_counters, %{"id" => Address.checksum(address_hash)}) counters_path: token_path(conn, :token_counters, %{"id" => Address.checksum(address_hash)})
) )
else else
{:restricted_access, _} ->
not_found(conn)
:error -> :error ->
not_found(conn) not_found(conn)

@ -1,6 +1,7 @@
defmodule BlockScoutWeb.Tokens.InventoryController do defmodule BlockScoutWeb.Tokens.InventoryController do
use BlockScoutWeb, :controller use BlockScoutWeb, :controller
alias BlockScoutWeb.AccessHelpers
alias BlockScoutWeb.Tokens.InventoryView alias BlockScoutWeb.Tokens.InventoryView
alias Explorer.{Chain, Market} alias Explorer.{Chain, Market}
alias Explorer.Chain.{Address, TokenTransfer} alias Explorer.Chain.{Address, TokenTransfer}
@ -10,7 +11,8 @@ defmodule BlockScoutWeb.Tokens.InventoryController do
def index(conn, %{"token_id" => address_hash_string, "type" => "JSON"} = params) do def index(conn, %{"token_id" => address_hash_string, "type" => "JSON"} = params) do
with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string), with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string),
{:ok, token} <- Chain.token_from_address_hash(address_hash) do {:ok, token} <- Chain.token_from_address_hash(address_hash),
{:ok, false} <- AccessHelpers.restricted_access?(address_hash_string, params) do
unique_tokens = unique_tokens =
Chain.address_to_unique_tokens( Chain.address_to_unique_tokens(
token.contract_address_hash, token.contract_address_hash,
@ -53,6 +55,9 @@ defmodule BlockScoutWeb.Tokens.InventoryController do
} }
) )
else else
{:restricted_access, _} ->
not_found(conn)
:error -> :error ->
not_found(conn) not_found(conn)
@ -61,11 +66,12 @@ defmodule BlockScoutWeb.Tokens.InventoryController do
end end
end end
def index(conn, %{"token_id" => address_hash_string}) do def index(conn, %{"token_id" => address_hash_string} = params) do
options = [necessity_by_association: %{[contract_address: :smart_contract] => :optional}] options = [necessity_by_association: %{[contract_address: :smart_contract] => :optional}]
with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string), with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string),
{:ok, token} <- Chain.token_from_address_hash(address_hash, options) do {:ok, token} <- Chain.token_from_address_hash(address_hash, options),
{:ok, false} <- AccessHelpers.restricted_access?(address_hash_string, params) do
render( render(
conn, conn,
"index.html", "index.html",
@ -74,6 +80,9 @@ defmodule BlockScoutWeb.Tokens.InventoryController do
counters_path: token_path(conn, :token_counters, %{"id" => Address.checksum(address_hash)}) counters_path: token_path(conn, :token_counters, %{"id" => Address.checksum(address_hash)})
) )
else else
{:restricted_access, _} ->
not_found(conn)
:error -> :error ->
not_found(conn) not_found(conn)

@ -1,15 +1,17 @@
defmodule BlockScoutWeb.Tokens.ReadContractController do defmodule BlockScoutWeb.Tokens.ReadContractController do
use BlockScoutWeb, :controller use BlockScoutWeb, :controller
alias BlockScoutWeb.AccessHelpers
alias Explorer.{Chain, Market} alias Explorer.{Chain, Market}
alias Explorer.Chain.Address alias Explorer.Chain.Address
def index(conn, %{"token_id" => address_hash_string}) do def index(conn, %{"token_id" => address_hash_string} = params) do
options = [necessity_by_association: %{[contract_address: :smart_contract] => :optional}] options = [necessity_by_association: %{[contract_address: :smart_contract] => :optional}]
with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string), with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string),
:ok <- Chain.check_verified_smart_contract_exists(address_hash), :ok <- Chain.check_verified_smart_contract_exists(address_hash),
{:ok, token} <- Chain.token_from_address_hash(address_hash, options) do {:ok, token} <- Chain.token_from_address_hash(address_hash, options),
{:ok, false} <- AccessHelpers.restricted_access?(address_hash_string, params) do
render( render(
conn, conn,
"index.html", "index.html",
@ -19,6 +21,9 @@ defmodule BlockScoutWeb.Tokens.ReadContractController do
counters_path: token_path(conn, :token_counters, %{"id" => Address.checksum(address_hash)}) counters_path: token_path(conn, :token_counters, %{"id" => Address.checksum(address_hash)})
) )
else else
{:restricted_access, _} ->
not_found(conn)
:not_found -> :not_found ->
not_found(conn) not_found(conn)

@ -3,10 +3,11 @@ defmodule BlockScoutWeb.Tokens.TokenController do
require Logger require Logger
alias BlockScoutWeb.AccessHelpers
alias Explorer.Chain alias Explorer.Chain
def show(conn, %{"id" => address_hash_string}) do def show(conn, %{"id" => address_hash_string}) do
redirect(conn, to: token_transfer_path(conn, :index, address_hash_string)) redirect(conn, to: AccessHelpers.get_path(conn, :token_transfer_path, :index, address_hash_string))
end end
def token_counters(conn, %{"id" => address_hash_string}) do def token_counters(conn, %{"id" => address_hash_string}) do

@ -1,6 +1,7 @@
defmodule BlockScoutWeb.Tokens.TransferController do defmodule BlockScoutWeb.Tokens.TransferController do
use BlockScoutWeb, :controller use BlockScoutWeb, :controller
alias BlockScoutWeb.AccessHelpers
alias BlockScoutWeb.Tokens.TransferView alias BlockScoutWeb.Tokens.TransferView
alias Explorer.{Chain, Market} alias Explorer.{Chain, Market}
alias Explorer.Chain.Address alias Explorer.Chain.Address
@ -15,7 +16,8 @@ defmodule BlockScoutWeb.Tokens.TransferController do
def index(conn, %{"token_id" => address_hash_string, "type" => "JSON"} = params) do def index(conn, %{"token_id" => address_hash_string, "type" => "JSON"} = params) do
with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string), with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string),
{:ok, token} <- Chain.token_from_address_hash(address_hash), {:ok, token} <- Chain.token_from_address_hash(address_hash),
token_transfers <- Chain.fetch_token_transfers_from_token_hash(address_hash, paging_options(params)) do token_transfers <- Chain.fetch_token_transfers_from_token_hash(address_hash, paging_options(params)),
{:ok, false} <- AccessHelpers.restricted_access?(address_hash_string, params) do
{token_transfers_paginated, next_page} = split_list_by_page(token_transfers) {token_transfers_paginated, next_page} = split_list_by_page(token_transfers)
next_page_path = next_page_path =
@ -46,6 +48,9 @@ defmodule BlockScoutWeb.Tokens.TransferController do
json(conn, %{items: transfers_json, next_page_path: next_page_path}) json(conn, %{items: transfers_json, next_page_path: next_page_path})
else else
{:restricted_access, _} ->
not_found(conn)
:error -> :error ->
unprocessable_entity(conn) unprocessable_entity(conn)
@ -54,11 +59,12 @@ defmodule BlockScoutWeb.Tokens.TransferController do
end end
end end
def index(conn, %{"token_id" => address_hash_string}) do def index(conn, %{"token_id" => address_hash_string} = params) do
options = [necessity_by_association: %{[contract_address: :smart_contract] => :optional}] options = [necessity_by_association: %{[contract_address: :smart_contract] => :optional}]
with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string), with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string),
{:ok, token} <- Chain.token_from_address_hash(address_hash, options) do {:ok, token} <- Chain.token_from_address_hash(address_hash, options),
{:ok, false} <- AccessHelpers.restricted_access?(address_hash_string, params) do
render( render(
conn, conn,
"index.html", "index.html",
@ -68,6 +74,9 @@ defmodule BlockScoutWeb.Tokens.TransferController do
token_total_supply_status: TokenTotalSupplyOnDemand.trigger_fetch(address_hash) token_total_supply_status: TokenTotalSupplyOnDemand.trigger_fetch(address_hash)
) )
else else
{:restricted_access, _} ->
not_found(conn)
:error -> :error ->
not_found(conn) not_found(conn)

@ -3,7 +3,7 @@ defmodule BlockScoutWeb.TransactionController do
import BlockScoutWeb.Chain, only: [paging_options: 1, next_page_params: 3, split_list_by_page: 1] import BlockScoutWeb.Chain, only: [paging_options: 1, next_page_params: 3, split_list_by_page: 1]
alias BlockScoutWeb.TransactionView alias BlockScoutWeb.{AccessHelpers, TransactionView}
alias Explorer.Chain alias Explorer.Chain
alias Phoenix.View alias Phoenix.View
@ -69,13 +69,16 @@ defmodule BlockScoutWeb.TransactionController do
with {:ok, transaction_hash} <- Chain.string_to_transaction_hash(id), with {:ok, transaction_hash} <- Chain.string_to_transaction_hash(id),
:ok <- Chain.check_transaction_exists(transaction_hash) do :ok <- Chain.check_transaction_exists(transaction_hash) do
if Chain.transaction_has_token_transfers?(transaction_hash) do if Chain.transaction_has_token_transfers?(transaction_hash) do
redirect(conn, to: transaction_token_transfer_path(conn, :index, id)) redirect(conn, to: AccessHelpers.get_path(conn, :transaction_token_transfer_path, :index, id))
else else
redirect(conn, to: transaction_internal_transaction_path(conn, :index, id)) redirect(conn, to: AccessHelpers.get_path(conn, :transaction_internal_transaction_path, :index, id))
end end
else else
:error -> conn |> put_status(422) |> render("invalid.html", transaction_hash: id) :error ->
:not_found -> conn |> put_status(404) |> render("not_found.html", transaction_hash: id) conn |> put_status(422) |> render("invalid.html", transaction_hash: id)
:not_found ->
conn |> put_status(404) |> render("not_found.html", transaction_hash: id)
end end
end end
end end

@ -3,14 +3,17 @@ defmodule BlockScoutWeb.TransactionInternalTransactionController do
import BlockScoutWeb.Chain, only: [paging_options: 1, next_page_params: 3, split_list_by_page: 1] import BlockScoutWeb.Chain, only: [paging_options: 1, next_page_params: 3, split_list_by_page: 1]
alias BlockScoutWeb.{InternalTransactionView, TransactionView} alias BlockScoutWeb.{AccessHelpers, InternalTransactionView, TransactionView}
alias Explorer.{Chain, Market} alias Explorer.{Chain, Market}
alias Explorer.ExchangeRates.Token alias Explorer.ExchangeRates.Token
alias Phoenix.View alias Phoenix.View
def index(conn, %{"transaction_id" => hash_string, "type" => "JSON"} = params) do def index(conn, %{"transaction_id" => transaction_hash_string, "type" => "JSON"} = params) do
with {:ok, hash} <- Chain.string_to_transaction_hash(hash_string), with {:ok, transaction_hash} <- Chain.string_to_transaction_hash(transaction_hash_string),
:ok <- Chain.check_transaction_exists(hash) do :ok <- Chain.check_transaction_exists(transaction_hash),
{:ok, transaction} <- Chain.hash_to_transaction(transaction_hash, []),
{:ok, false} <- AccessHelpers.restricted_access?(to_string(transaction.from_address_hash), params),
{:ok, false} <- AccessHelpers.restricted_access?(to_string(transaction.to_address_hash), params) do
full_options = full_options =
Keyword.merge( Keyword.merge(
[ [
@ -24,7 +27,7 @@ defmodule BlockScoutWeb.TransactionInternalTransactionController do
paging_options(params) paging_options(params)
) )
internal_transactions_plus_one = Chain.transaction_to_internal_transactions(hash, full_options) internal_transactions_plus_one = Chain.transaction_to_internal_transactions(transaction_hash, full_options)
{internal_transactions, next_page} = split_list_by_page(internal_transactions_plus_one) {internal_transactions, next_page} = split_list_by_page(internal_transactions_plus_one)
@ -37,7 +40,7 @@ defmodule BlockScoutWeb.TransactionInternalTransactionController do
transaction_internal_transaction_path( transaction_internal_transaction_path(
conn, conn,
:index, :index,
hash, transaction_hash,
Map.delete(next_page_params, "type") Map.delete(next_page_params, "type")
) )
end end
@ -60,25 +63,37 @@ defmodule BlockScoutWeb.TransactionInternalTransactionController do
} }
) )
else else
{:restricted_access, _} ->
conn
|> put_status(404)
|> put_view(TransactionView)
|> render("not_found.html", transaction_hash: transaction_hash_string)
:error -> :error ->
conn conn
|> put_status(422) |> put_status(422)
|> put_view(TransactionView) |> put_view(TransactionView)
|> render("invalid.html", transaction_hash: hash_string) |> render("invalid.html", transaction_hash: transaction_hash_string)
{:error, :not_found} ->
conn
|> put_status(404)
|> put_view(TransactionView)
|> render("not_found.html", transaction_hash: transaction_hash_string)
:not_found -> :not_found ->
conn conn
|> put_status(404) |> put_status(404)
|> put_view(TransactionView) |> put_view(TransactionView)
|> render("not_found.html", transaction_hash: hash_string) |> render("not_found.html", transaction_hash: transaction_hash_string)
end end
end end
def index(conn, %{"transaction_id" => hash_string}) do def index(conn, %{"transaction_id" => transaction_hash_string} = params) do
with {:ok, hash} <- Chain.string_to_transaction_hash(hash_string), with {:ok, transaction_hash} <- Chain.string_to_transaction_hash(transaction_hash_string),
{:ok, transaction} <- {:ok, transaction} <-
Chain.hash_to_transaction( Chain.hash_to_transaction(
hash, transaction_hash,
necessity_by_association: %{ necessity_by_association: %{
:block => :optional, :block => :optional,
[created_contract_address: :names] => :optional, [created_contract_address: :names] => :optional,
@ -87,28 +102,36 @@ defmodule BlockScoutWeb.TransactionInternalTransactionController do
[to_address: :smart_contract] => :optional, [to_address: :smart_contract] => :optional,
:token_transfers => :optional :token_transfers => :optional
} }
) do ),
{:ok, false} <- AccessHelpers.restricted_access?(to_string(transaction.from_address_hash), params),
{:ok, false} <- AccessHelpers.restricted_access?(to_string(transaction.to_address_hash), params) do
render( render(
conn, conn,
"index.html", "index.html",
exchange_rate: Market.get_exchange_rate(Explorer.coin()) || Token.null(), exchange_rate: Market.get_exchange_rate(Explorer.coin()) || Token.null(),
current_path: current_path(conn), current_path: current_path(conn),
block_height: Chain.block_height(), block_height: Chain.block_height(),
show_token_transfers: Chain.transaction_has_token_transfers?(hash), show_token_transfers: Chain.transaction_has_token_transfers?(transaction_hash),
transaction: transaction transaction: transaction
) )
else else
{:restricted_access, _} ->
conn
|> put_status(404)
|> put_view(TransactionView)
|> render("not_found.html", transaction_hash: transaction_hash_string)
:error -> :error ->
conn conn
|> put_status(422) |> put_status(422)
|> put_view(TransactionView) |> put_view(TransactionView)
|> render("invalid.html", transaction_hash: hash_string) |> render("invalid.html", transaction_hash: transaction_hash_string)
{:error, :not_found} -> {:error, :not_found} ->
conn conn
|> put_status(404) |> put_status(404)
|> put_view(TransactionView) |> put_view(TransactionView)
|> render("not_found.html", transaction_hash: hash_string) |> render("not_found.html", transaction_hash: transaction_hash_string)
end end
end end
end end

@ -3,7 +3,7 @@ defmodule BlockScoutWeb.TransactionLogController do
import BlockScoutWeb.Chain, only: [paging_options: 1, next_page_params: 3, split_list_by_page: 1] import BlockScoutWeb.Chain, only: [paging_options: 1, next_page_params: 3, split_list_by_page: 1]
alias BlockScoutWeb.{TransactionLogView, TransactionView} alias BlockScoutWeb.{AccessHelpers, TransactionLogView, TransactionView}
alias Explorer.{Chain, Market} alias Explorer.{Chain, Market}
alias Explorer.ExchangeRates.Token alias Explorer.ExchangeRates.Token
alias Phoenix.View alias Phoenix.View
@ -13,7 +13,9 @@ defmodule BlockScoutWeb.TransactionLogController do
{:ok, transaction} <- {:ok, transaction} <-
Chain.hash_to_transaction(transaction_hash, Chain.hash_to_transaction(transaction_hash,
necessity_by_association: %{[to_address: :smart_contract] => :optional} necessity_by_association: %{[to_address: :smart_contract] => :optional}
) do ),
{:ok, false} <- AccessHelpers.restricted_access?(to_string(transaction.from_address_hash), params),
{:ok, false} <- AccessHelpers.restricted_access?(to_string(transaction.to_address_hash), params) do
full_options = full_options =
Keyword.merge( Keyword.merge(
[ [
@ -57,6 +59,12 @@ defmodule BlockScoutWeb.TransactionLogController do
} }
) )
else else
{:restricted_access, _} ->
conn
|> put_status(404)
|> put_view(TransactionView)
|> render("not_found.html", transaction_hash: transaction_hash_string)
:error -> :error ->
conn conn
|> put_status(422) |> put_status(422)
@ -71,7 +79,7 @@ defmodule BlockScoutWeb.TransactionLogController do
end end
end end
def index(conn, %{"transaction_id" => transaction_hash_string}) do def index(conn, %{"transaction_id" => transaction_hash_string} = params) do
with {:ok, transaction_hash} <- Chain.string_to_transaction_hash(transaction_hash_string), with {:ok, transaction_hash} <- Chain.string_to_transaction_hash(transaction_hash_string),
{:ok, transaction} <- {:ok, transaction} <-
Chain.hash_to_transaction( Chain.hash_to_transaction(
@ -84,7 +92,9 @@ defmodule BlockScoutWeb.TransactionLogController do
[to_address: :smart_contract] => :optional, [to_address: :smart_contract] => :optional,
:token_transfers => :optional :token_transfers => :optional
} }
) do ),
{:ok, false} <- AccessHelpers.restricted_access?(to_string(transaction.from_address_hash), params),
{:ok, false} <- AccessHelpers.restricted_access?(to_string(transaction.to_address_hash), params) do
render( render(
conn, conn,
"index.html", "index.html",
@ -95,6 +105,12 @@ defmodule BlockScoutWeb.TransactionLogController do
exchange_rate: Market.get_exchange_rate(Explorer.coin()) || Token.null() exchange_rate: Market.get_exchange_rate(Explorer.coin()) || Token.null()
) )
else else
{:restricted_access, _} ->
conn
|> put_status(404)
|> put_view(TransactionView)
|> render("not_found.html", transaction_hash: transaction_hash_string)
:error -> :error ->
conn conn
|> put_status(422) |> put_status(422)

@ -1,14 +1,14 @@
defmodule BlockScoutWeb.TransactionRawTraceController do defmodule BlockScoutWeb.TransactionRawTraceController do
use BlockScoutWeb, :controller use BlockScoutWeb, :controller
alias BlockScoutWeb.TransactionView alias BlockScoutWeb.{AccessHelpers, TransactionView}
alias EthereumJSONRPC alias EthereumJSONRPC
alias Explorer.{Chain, Market} alias Explorer.{Chain, Market}
alias Explorer.Chain.Import alias Explorer.Chain.Import
alias Explorer.Chain.Import.Runner.InternalTransactions alias Explorer.Chain.Import.Runner.InternalTransactions
alias Explorer.ExchangeRates.Token alias Explorer.ExchangeRates.Token
def index(conn, %{"transaction_id" => hash_string}) do def index(conn, %{"transaction_id" => hash_string} = params) do
with {:ok, hash} <- Chain.string_to_transaction_hash(hash_string), with {:ok, hash} <- Chain.string_to_transaction_hash(hash_string),
{:ok, transaction} <- {:ok, transaction} <-
Chain.hash_to_transaction( Chain.hash_to_transaction(
@ -21,7 +21,9 @@ defmodule BlockScoutWeb.TransactionRawTraceController do
[to_address: :smart_contract] => :optional, [to_address: :smart_contract] => :optional,
:token_transfers => :optional :token_transfers => :optional
} }
) do ),
{:ok, false} <- AccessHelpers.restricted_access?(to_string(transaction.from_address_hash), params),
{:ok, false} <- AccessHelpers.restricted_access?(to_string(transaction.to_address_hash), params) do
internal_transactions = Chain.all_transaction_to_internal_transactions(hash) internal_transactions = Chain.all_transaction_to_internal_transactions(hash)
first_trace_exists = first_trace_exists =
@ -76,6 +78,12 @@ defmodule BlockScoutWeb.TransactionRawTraceController do
transaction: transaction transaction: transaction
) )
else else
{:restricted_access, _} ->
conn
|> put_status(404)
|> put_view(TransactionView)
|> render("not_found.html", transaction_hash: hash_string)
:error -> :error ->
conn conn
|> put_status(422) |> put_status(422)

@ -3,7 +3,7 @@ defmodule BlockScoutWeb.TransactionTokenTransferController do
import BlockScoutWeb.Chain, only: [paging_options: 1, next_page_params: 3, split_list_by_page: 1] import BlockScoutWeb.Chain, only: [paging_options: 1, next_page_params: 3, split_list_by_page: 1]
alias BlockScoutWeb.{TransactionTokenTransferView, TransactionView} alias BlockScoutWeb.{AccessHelpers, TransactionTokenTransferView, TransactionView}
alias Explorer.{Chain, Market} alias Explorer.{Chain, Market}
alias Explorer.ExchangeRates.Token alias Explorer.ExchangeRates.Token
alias Phoenix.View alias Phoenix.View
@ -11,9 +11,16 @@ defmodule BlockScoutWeb.TransactionTokenTransferController do
{:ok, burn_address_hash} = Chain.string_to_address_hash("0x0000000000000000000000000000000000000000") {:ok, burn_address_hash} = Chain.string_to_address_hash("0x0000000000000000000000000000000000000000")
@burn_address_hash burn_address_hash @burn_address_hash burn_address_hash
def index(conn, %{"transaction_id" => hash_string, "type" => "JSON"} = params) do def index(conn, %{"transaction_id" => transaction_hash_string, "type" => "JSON"} = params) do
with {:ok, hash} <- Chain.string_to_transaction_hash(hash_string), with {:ok, transaction_hash} <- Chain.string_to_transaction_hash(transaction_hash_string),
:ok <- Chain.check_transaction_exists(hash) do :ok <- Chain.check_transaction_exists(transaction_hash),
{:ok, transaction} <-
Chain.hash_to_transaction(
transaction_hash,
[]
),
{:ok, false} <- AccessHelpers.restricted_access?(to_string(transaction.from_address_hash), params),
{:ok, false} <- AccessHelpers.restricted_access?(to_string(transaction.to_address_hash), params) do
full_options = full_options =
Keyword.merge( Keyword.merge(
[ [
@ -26,7 +33,7 @@ defmodule BlockScoutWeb.TransactionTokenTransferController do
paging_options(params) paging_options(params)
) )
token_transfers_plus_one = Chain.transaction_to_token_transfers(hash, full_options) token_transfers_plus_one = Chain.transaction_to_token_transfers(transaction_hash, full_options)
{token_transfers, next_page} = split_list_by_page(token_transfers_plus_one) {token_transfers, next_page} = split_list_by_page(token_transfers_plus_one)
@ -36,7 +43,7 @@ defmodule BlockScoutWeb.TransactionTokenTransferController do
nil nil
next_page_params -> next_page_params ->
transaction_token_transfer_path(conn, :index, hash, Map.delete(next_page_params, "type")) transaction_token_transfer_path(conn, :index, transaction_hash, Map.delete(next_page_params, "type"))
end end
items = items =
@ -59,25 +66,37 @@ defmodule BlockScoutWeb.TransactionTokenTransferController do
} }
) )
else else
{:restricted_access, _} ->
conn
|> put_status(404)
|> put_view(TransactionView)
|> render("not_found.html", transaction_hash: transaction_hash_string)
:error -> :error ->
conn conn
|> put_status(422) |> put_status(422)
|> put_view(TransactionView) |> put_view(TransactionView)
|> render("invalid.html", transaction_hash: hash_string) |> render("invalid.html", transaction_hash: transaction_hash_string)
{:error, :not_found} ->
conn
|> put_status(404)
|> put_view(TransactionView)
|> render("not_found.html", transaction_hash: transaction_hash_string)
:not_found -> :not_found ->
conn conn
|> put_status(404) |> put_status(404)
|> put_view(TransactionView) |> put_view(TransactionView)
|> render("not_found.html", transaction_hash: hash_string) |> render("not_found.html", transaction_hash: transaction_hash_string)
end end
end end
def index(conn, %{"transaction_id" => hash_string}) do def index(conn, %{"transaction_id" => transaction_hash_string} = params) do
with {:ok, hash} <- Chain.string_to_transaction_hash(hash_string), with {:ok, transaction_hash} <- Chain.string_to_transaction_hash(transaction_hash_string),
{:ok, transaction} <- {:ok, transaction} <-
Chain.hash_to_transaction( Chain.hash_to_transaction(
hash, transaction_hash,
necessity_by_association: %{ necessity_by_association: %{
:block => :optional, :block => :optional,
[created_contract_address: :names] => :optional, [created_contract_address: :names] => :optional,
@ -86,7 +105,9 @@ defmodule BlockScoutWeb.TransactionTokenTransferController do
[to_address: :smart_contract] => :optional, [to_address: :smart_contract] => :optional,
:token_transfers => :optional :token_transfers => :optional
} }
) do ),
{:ok, false} <- AccessHelpers.restricted_access?(to_string(transaction.from_address_hash), params),
{:ok, false} <- AccessHelpers.restricted_access?(to_string(transaction.to_address_hash), params) do
render( render(
conn, conn,
"index.html", "index.html",
@ -97,17 +118,29 @@ defmodule BlockScoutWeb.TransactionTokenTransferController do
transaction: transaction transaction: transaction
) )
else else
:not_found ->
conn
|> put_status(404)
|> put_view(TransactionView)
|> render("not_found.html", transaction_hash: transaction_hash_string)
:error -> :error ->
conn conn
|> put_status(422) |> put_status(422)
|> put_view(TransactionView) |> put_view(TransactionView)
|> render("invalid.html", transaction_hash: hash_string) |> render("invalid.html", transaction_hash: transaction_hash_string)
{:error, :not_found} -> {:error, :not_found} ->
conn conn
|> put_status(404) |> put_status(404)
|> put_view(TransactionView) |> put_view(TransactionView)
|> render("not_found.html", transaction_hash: hash_string) |> render("not_found.html", transaction_hash: transaction_hash_string)
{:restricted_access, _} ->
conn
|> put_status(404)
|> put_view(TransactionView)
|> render("not_found.html", transaction_hash: transaction_hash_string)
end end
end end
end end

@ -19,7 +19,7 @@
<p <p
class="address-current-balance" class="address-current-balance"
data-token-balance-dropdown data-token-balance-dropdown
data-api_path="<%= address_token_balance_path(BlockScoutWeb.Endpoint, :index, @address.hash) %>" data-api_path="<%= AccessHelpers.get_path(@conn, :address_token_balance_path, :index, @address.hash) %>"
> >
<span data-loading class="mb-0"> <span data-loading class="mb-0">
<span class="loading-spinner-small mr-2"> <span class="loading-spinner-small mr-2">

@ -2,21 +2,21 @@
<%= link( <%= link(
gettext("Transactions"), gettext("Transactions"),
class: "card-tab #{tab_status("transactions", @conn.request_path)}", class: "card-tab #{tab_status("transactions", @conn.request_path)}",
to: address_transaction_path(@conn, :index, @address.hash) to: AccessHelpers.get_path(@conn, :address_transaction_path, :index, @address.hash)
) %> ) %>
<%= if Chain.check_if_token_transfers_at_address(@address.hash) do %> <%= if Chain.check_if_token_transfers_at_address(@address.hash) do %>
<%= link( <%= link(
gettext("Token Transfers"), gettext("Token Transfers"),
class: "card-tab #{tab_status("token-transfers", @conn.request_path)}", class: "card-tab #{tab_status("token-transfers", @conn.request_path)}",
"data-test": "token_transfers_tab_link", "data-test": "token_transfers_tab_link",
to: address_token_transfers_path(@conn, :index, @address.hash) to: AccessHelpers.get_path(@conn, :address_token_transfers_path, :index, @address.hash)
) %> ) %>
<% end %> <% end %>
<%= if Chain.check_if_tokens_at_address(@address.hash) do %> <%= if Chain.check_if_tokens_at_address(@address.hash) do %>
<%= link( <%= link(
gettext("Tokens"), gettext("Tokens"),
class: "card-tab #{tab_status("tokens", @conn.request_path)}", class: "card-tab #{tab_status("tokens", @conn.request_path)}",
to: address_token_path(@conn, :index, @address.hash), to: AccessHelpers.get_path(@conn, :address_token_path, :index, @address.hash),
"data-test": "tokens_tab_link" "data-test": "tokens_tab_link"
) %> ) %>
<% end %> <% end %>
@ -24,19 +24,19 @@
gettext("Internal Transactions"), gettext("Internal Transactions"),
class: "card-tab #{tab_status("internal-transactions", @conn.request_path)}", class: "card-tab #{tab_status("internal-transactions", @conn.request_path)}",
"data-test": "internal_transactions_tab_link", "data-test": "internal_transactions_tab_link",
to: address_internal_transaction_path(@conn, :index, @address.hash) to: AccessHelpers.get_path(@conn, :address_internal_transaction_path, :index, @address.hash)
) %> ) %>
<%= link( <%= link(
gettext("Coin Balance History"), gettext("Coin Balance History"),
class: "card-tab #{tab_status("coin-balances", @conn.request_path)}", class: "card-tab #{tab_status("coin-balances", @conn.request_path)}",
"data-test": "coin_balance_tab_link", "data-test": "coin_balance_tab_link",
to: address_coin_balance_path(@conn, :index, @address.hash) to: AccessHelpers.get_path(@conn, :address_coin_balance_path, :index, @address.hash)
) %> ) %>
<%= if Chain.check_if_logs_at_address(@address.hash) do %> <%= if Chain.check_if_logs_at_address(@address.hash) do %>
<%= link( <%= link(
gettext("Logs"), gettext("Logs"),
class: "card-tab #{tab_status("logs", @conn.request_path)}", class: "card-tab #{tab_status("logs", @conn.request_path)}",
to: address_logs_path(@conn, :index, @address.hash) to: AccessHelpers.get_path(@conn, :address_logs_path, :index, @address.hash)
) %> ) %>
<% end %> <% end %>
<%= if Chain.check_if_validated_blocks_at_address(@address.hash) do %> <%= if Chain.check_if_validated_blocks_at_address(@address.hash) do %>
@ -44,12 +44,12 @@
gettext("Blocks Validated"), gettext("Blocks Validated"),
class: "card-tab #{tab_status("validations", @conn.request_path)}", class: "card-tab #{tab_status("validations", @conn.request_path)}",
"data-test": "validations_tab_link", "data-test": "validations_tab_link",
to: address_validation_path(@conn, :index, @address.hash) to: AccessHelpers.get_path(@conn, :address_validation_path, :index, @address.hash)
) %> ) %>
<% end %> <% end %>
<%= if contract?(@address) do %> <%= if contract?(@address) do %>
<%= link( <%= link(
to: address_contract_path(@conn, :index, @address.hash), to: AccessHelpers.get_path(@conn, :address_contract_path, :index, @address.hash),
class: "card-tab #{tab_status("contracts", @conn.request_path)}") do %> class: "card-tab #{tab_status("contracts", @conn.request_path)}") do %>
<%= gettext("Code") %> <%= gettext("Code") %>
<%= if smart_contract_verified?(@address) do %> <%= if smart_contract_verified?(@address) do %>
@ -59,7 +59,7 @@
<% end %> <% end %>
<%= if has_decompiled_code?(@address) do %> <%= if has_decompiled_code?(@address) do %>
<%= link( <%= link(
to: address_decompiled_contract_path(@conn, :index, @address.hash), to: AccessHelpers.get_path(@conn, :address_decompiled_contract_path, :index, @address.hash),
class: "card-tab #{tab_status("decompiled-contracts", @conn.request_path)}") do %> class: "card-tab #{tab_status("decompiled-contracts", @conn.request_path)}") do %>
<%= gettext("Decompiled code") %> <%= gettext("Decompiled code") %>
<i class="far fa-check-circle"></i> <i class="far fa-check-circle"></i>
@ -68,28 +68,28 @@
<%= if smart_contract_with_read_only_functions?(@address) do %> <%= if smart_contract_with_read_only_functions?(@address) do %>
<%= link( <%= link(
gettext("Read Contract"), gettext("Read Contract"),
to: address_read_contract_path(@conn, :index, @address.hash), to: AccessHelpers.get_path(@conn, :address_read_contract_path, :index, @address.hash),
class: "card-tab #{tab_status("read-contract", @conn.request_path)}") class: "card-tab #{tab_status("read-contract", @conn.request_path)}")
%> %>
<% end %> <% end %>
<%= if smart_contract_is_proxy?(@address) do %> <%= if smart_contract_is_proxy?(@address) do %>
<%= link( <%= link(
gettext("Read Proxy"), gettext("Read Proxy"),
to: address_read_proxy_path(@conn, :index, @address.hash), to: AccessHelpers.get_path(@conn, :address_read_proxy_path, :index, @address.hash),
class: "card-tab #{tab_status("read-proxy", @conn.request_path)}") class: "card-tab #{tab_status("read-proxy", @conn.request_path)}")
%> %>
<% end %> <% end %>
<%= if smart_contract_with_write_functions?(@address) do %> <%= if smart_contract_with_write_functions?(@address) do %>
<%= link( <%= link(
gettext("Write Contract"), gettext("Write Contract"),
to: address_write_contract_path(@conn, :index, @address.hash), to: AccessHelpers.get_path(@conn, :address_write_contract_path, :index, @address.hash),
class: "card-tab #{tab_status("write-contract", @conn.request_path)}") class: "card-tab #{tab_status("write-contract", @conn.request_path)}")
%> %>
<% end %> <% end %>
<%= if smart_contract_with_write_functions?(@address) && smart_contract_is_proxy?(@address) do %> <%= if smart_contract_with_write_functions?(@address) && smart_contract_is_proxy?(@address) do %>
<%= link( <%= link(
gettext("Write Proxy"), gettext("Write Proxy"),
to: address_write_proxy_path(@conn, :index, @address.hash), to: AccessHelpers.get_path(@conn, :address_write_proxy_path, :index, @address.hash),
class: "card-tab #{tab_status("write-proxy", @conn.request_path)}") class: "card-tab #{tab_status("write-proxy", @conn.request_path)}")
%> %>
<% end %> <% end %>

@ -27,7 +27,7 @@
<span><%= gettext("There was a problem loading the chart.") %></span> <span><%= gettext("There was a problem loading the chart.") %></span>
</button> </button>
<div data-chart-container style="display: none;" class="mb-4"> <div data-chart-container style="display: none;" class="mb-4">
<canvas data-chart="coinBalanceHistoryChart" data-coin_balance_history_data_path="<%= address_coin_balance_by_day_path(@conn, :index, @address) %>" width="350" height="152"></canvas> <canvas data-chart="coinBalanceHistoryChart" data-coin_balance_history_data_path="<%= AccessHelpers.get_path(@conn, :address_coin_balance_by_day_path, :index, @address.hash) %>" width="350" height="152"></canvas>
</div> </div>
<%= render BlockScoutWeb.CommonComponentsView, "_pagination_container.html", position: "top", cur_page_number: "1", show_pagination_limit: true, data_next_page_button: true, data_prev_page_button: true %> <%= render BlockScoutWeb.CommonComponentsView, "_pagination_container.html", position: "top", cur_page_number: "1", show_pagination_limit: true, data_next_page_button: true, data_prev_page_button: true %>

@ -25,29 +25,19 @@
<div class="dropdown-menu dropdown-menu-right filter" aria-labelledby="dropdownMenu2"> <div class="dropdown-menu dropdown-menu-right filter" aria-labelledby="dropdownMenu2">
<%= link( <%= link(
gettext("All"), gettext("All"),
to: address_internal_transaction_path(@conn, :index, @address.hash), to: AccessHelpers.get_path(@conn, :address_internal_transaction_path, :index, @address.hash),
class: "address__link address__link--active dropdown-item", class: "address__link address__link--active dropdown-item",
"data-test": "filter_option" "data-test": "filter_option"
) %> ) %>
<%= link( <%= link(
gettext("To"), gettext("To"),
to: address_internal_transaction_path( to: AccessHelpers.get_path(@conn, :address_internal_transaction_path, :index, @address.hash, %{:filter => "to"}),
@conn,
:index,
@address.hash,
filter: "to"
),
class: "address__link address__link--active dropdown-item", class: "address__link address__link--active dropdown-item",
"data-test": "filter_option" "data-test": "filter_option"
) %> ) %>
<%= link( <%= link(
gettext("From"), gettext("From"),
to: address_internal_transaction_path( to: AccessHelpers.get_path(@conn, :address_internal_transaction_path, :index, @address.hash, %{:filter => "from"}),
@conn,
:index,
@address.hash,
filter: "from"
),
class: "address__link address__link--active dropdown-item", class: "address__link address__link--active dropdown-item",
"data-test": "filter_option" "data-test": "filter_option"
) %> ) %>

@ -23,29 +23,19 @@
<div class="dropdown-menu dropdown-menu-right filter" aria-labelledby="dropdownMenu2"> <div class="dropdown-menu dropdown-menu-right filter" aria-labelledby="dropdownMenu2">
<%= link( <%= link(
gettext("All"), gettext("All"),
to: address_token_transfers_path(@conn, :index, to_string(@address.hash)), to: AccessHelpers.get_path(@conn, :address_token_transfers_path, :index, to_string(@address.hash)),
class: "address__link address__link--active dropdown-item", class: "address__link address__link--active dropdown-item",
"data-test": "filter_option" "data-test": "filter_option"
) %> ) %>
<%= link( <%= link(
gettext("To"), gettext("To"),
to: address_token_transfers_path( to: AccessHelpers.get_path(@conn, :address_token_transfers_path, :index, to_string(@address.hash), %{:filter => "to"}),
@conn,
:index,
to_string(@address.hash),
filter: "to"
),
class: "address__link address__link--active dropdown-item", class: "address__link address__link--active dropdown-item",
"data-test": "filter_option" "data-test": "filter_option"
) %> ) %>
<%= link( <%= link(
gettext("From"), gettext("From"),
to: address_token_transfers_path( to: AccessHelpers.get_path(@conn, :address_token_transfers_path, :index, to_string(@address.hash), %{:filter => "from"}),
@conn,
:index,
to_string(@address.hash),
filter: "from"
),
class: "address__link address__link--active dropdown-item", class: "address__link address__link--active dropdown-item",
"data-test": "filter_option" "data-test": "filter_option"
) %> ) %>

@ -21,29 +21,19 @@
<div class="dropdown-menu dropdown-menu-right filter" aria-labelledby="dropdownMenu2"> <div class="dropdown-menu dropdown-menu-right filter" aria-labelledby="dropdownMenu2">
<%= link( <%= link(
gettext("All"), gettext("All"),
to: address_transaction_path(@conn, :index, @address.hash), to: AccessHelpers.get_path(@conn, :address_transaction_path, :index, @address.hash),
class: "address__link address__link--active dropdown-item", class: "address__link address__link--active dropdown-item",
"data-test": "filter_option" "data-test": "filter_option"
) %> ) %>
<%= link( <%= link(
gettext("To"), gettext("To"),
to: address_transaction_path( to: AccessHelpers.get_path(@conn, :address_transaction_path, :index, @address.hash, %{:filter => "to"}),
@conn,
:index,
@address.hash,
filter: "to"
),
class: "address__link address__link--active dropdown-item", class: "address__link address__link--active dropdown-item",
"data-test": "filter_option" "data-test": "filter_option"
) %> ) %>
<%= link( <%= link(
gettext("From"), gettext("From"),
to: address_transaction_path( to: AccessHelpers.get_path(@conn, :address_transaction_path, :index, @address.hash, %{:filter => "from"}),
@conn,
:index,
@address.hash,
filter: "from"
),
class: "address__link address__link--active dropdown-item", class: "address__link address__link--active dropdown-item",
"data-test": "filter_option" "data-test": "filter_option"
) %> ) %>

@ -65,7 +65,7 @@
<div class="d-flex flex-column flex-md-row justify-content-start text-muted"> <div class="d-flex flex-column flex-md-row justify-content-start text-muted">
<span class="mr-4 mb-3 mb-md-0"> <span class="mr-4 mb-3 mb-md-0">
<%= link to: <%= link to:
address_path(@conn, :show, Address.checksum(@token.contract_address_hash)), AccessHelpers.get_path(@conn, :address_path, :show, Address.checksum(@token.contract_address_hash)),
"data-test": "token_contract_address" "data-test": "token_contract_address"
do %> do %>
<%= gettext "View Contract" %> <%= gettext "View Contract" %>

@ -2,28 +2,28 @@
<%= link( <%= link(
gettext("Token Transfers"), gettext("Token Transfers"),
class: "card-tab #{tab_status("token-transfers", @conn.request_path)}", class: "card-tab #{tab_status("token-transfers", @conn.request_path)}",
to: token_path(@conn, :show, @token.contract_address_hash) to: AccessHelpers.get_path(@conn, :token_path, :show, @token.contract_address_hash)
) )
%> %>
<%= link( <%= link(
gettext("Token Holders"), gettext("Token Holders"),
class: "card-tab #{tab_status("token-holders", @conn.request_path)}", class: "card-tab #{tab_status("token-holders", @conn.request_path)}",
"data-test": "token_holders_tab", "data-test": "token_holders_tab",
to: token_holder_path(@conn, :index, Address.checksum(@token.contract_address_hash)) to: AccessHelpers.get_path(@conn, :token_holder_path, :index, Address.checksum(@token.contract_address_hash))
) )
%> %>
<%= if display_inventory?(@token) do %> <%= if display_inventory?(@token) do %>
<%= link( <%= link(
gettext("Inventory"), gettext("Inventory"),
class: "card-tab #{tab_status("inventory", @conn.request_path)}", class: "card-tab #{tab_status("inventory", @conn.request_path)}",
to: token_inventory_path(@conn, :index, Address.checksum(@token.contract_address_hash)) to: AccessHelpers.get_path(@conn, :token_inventory_path, :index, Address.checksum(@token.contract_address_hash))
) )
%> %>
<% end %> <% end %>
<%= if smart_contract_with_read_only_functions?(@token) do %> <%= if smart_contract_with_read_only_functions?(@token) do %>
<%= link( <%= link(
gettext("Read Contract"), gettext("Read Contract"),
to: token_read_contract_path(@conn, :index, Address.checksum(@token.contract_address_hash)), to: AccessHelpers.get_path(@conn, :token_read_contract_path, :index, Address.checksum(@token.contract_address_hash)),
class: "card-tab #{tab_status("read-contract", @conn.request_path)}") class: "card-tab #{tab_status("read-contract", @conn.request_path)}")
%> %>
<% end %> <% end %>

@ -3,26 +3,26 @@
<%= link( <%= link(
gettext("Token Transfers"), gettext("Token Transfers"),
class: "card-tab #{tab_status("token-transfers", @conn.request_path)}", class: "card-tab #{tab_status("token-transfers", @conn.request_path)}",
to: transaction_token_transfer_path(@conn, :index, @transaction) to: AccessHelpers.get_path(@conn, :transaction_token_transfer_path, :index, @transaction)
) )
%> %>
<% end %> <% end %>
<%= link( <%= link(
gettext("Internal Transactions"), gettext("Internal Transactions"),
class: "card-tab #{tab_status("internal-transactions", @conn.request_path)}", class: "card-tab #{tab_status("internal-transactions", @conn.request_path)}",
to: transaction_internal_transaction_path(@conn, :index, @transaction) to: AccessHelpers.get_path(@conn, :transaction_internal_transaction_path, :index, @transaction)
) )
%> %>
<%= link( <%= link(
gettext("Logs"), gettext("Logs"),
class: "card-tab #{tab_status("logs", @conn.request_path)}", class: "card-tab #{tab_status("logs", @conn.request_path)}",
to: transaction_log_path(@conn, :index, @transaction), to: AccessHelpers.get_path(@conn, :transaction_log_path, :index, @transaction),
"data-test": "transaction_logs_link" "data-test": "transaction_logs_link"
) )
%> %>
<%= link( <%= link(
gettext("Raw Trace"), gettext("Raw Trace"),
class: "card-tab #{tab_status("raw-trace", @conn.request_path)}", class: "card-tab #{tab_status("raw-trace", @conn.request_path)}",
to: transaction_raw_trace_path(@conn, :index, @transaction) to: AccessHelpers.get_path(@conn, :transaction_raw_trace_path, :index, @transaction)
) %> ) %>
</div> </div>

@ -0,0 +1,58 @@
defmodule BlockScoutWeb.AccessHelpers do
@moduledoc """
Helpers to restrict access to some pages filtering by address
"""
alias BlockScoutWeb.WebRouter.Helpers
alias Plug.Conn
defp get_restricted_key(%Phoenix.Socket{}) do
nil
end
defp get_restricted_key(conn) do
conn_with_params = Conn.fetch_query_params(conn)
conn_with_params.query_params["key"]
end
def restricted_access?(address_hash, params) do
formatted_address_hash = String.downcase(address_hash)
key = if params && Map.has_key?(params, "key"), do: Map.get(params, "key"), else: nil
restricted_list_var = Application.get_env(:block_scout_web, :restricted_list)
restricted_list = (restricted_list_var && String.split(restricted_list_var, ",")) || []
formatted_restricted_list =
restricted_list
|> Enum.map(fn addr ->
String.downcase(addr)
end)
address_restricted =
formatted_restricted_list
|> Enum.member?(formatted_address_hash)
correct_key = key && key == Application.get_env(:block_scout_web, :restricted_list_key)
if address_restricted && !correct_key, do: {:restricted_access, true}, else: {:ok, false}
end
def get_path(conn, path, template, address_hash) do
basic_args = [conn, template, address_hash]
key = get_restricted_key(conn)
# credo:disable-for-next-line
full_args = if key, do: basic_args ++ [%{:key => key}], else: basic_args
apply(Helpers, path, full_args)
end
def get_path(conn, path, template, address_hash, additional_params) do
basic_args = [conn, template, address_hash]
key = get_restricted_key(conn)
full_additional_params = if key, do: Map.put(additional_params, :key, key), else: additional_params
# credo:disable-for-next-line
full_args = basic_args ++ [full_additional_params]
apply(Helpers, path, full_args)
end
end

@ -1,6 +1,7 @@
defmodule BlockScoutWeb.AddressCoinBalanceView do defmodule BlockScoutWeb.AddressCoinBalanceView do
use BlockScoutWeb, :view use BlockScoutWeb, :view
alias BlockScoutWeb.AccessHelpers
alias Explorer.Chain.Wei alias Explorer.Chain.Wei
def format(%Wei{} = value) do def format(%Wei{} = value) do

@ -1,6 +1,8 @@
defmodule BlockScoutWeb.AddressInternalTransactionView do defmodule BlockScoutWeb.AddressInternalTransactionView do
use BlockScoutWeb, :view use BlockScoutWeb, :view
alias BlockScoutWeb.AccessHelpers
def format_current_filter(filter) do def format_current_filter(filter) do
case filter do case filter do
"to" -> gettext("To") "to" -> gettext("To")

@ -1,6 +1,8 @@
defmodule BlockScoutWeb.AddressTokenTransferView do defmodule BlockScoutWeb.AddressTokenTransferView do
use BlockScoutWeb, :view use BlockScoutWeb, :view
alias BlockScoutWeb.AccessHelpers
def format_current_filter(filter) do def format_current_filter(filter) do
case filter do case filter do
"to" -> gettext("To") "to" -> gettext("To")

@ -1,6 +1,7 @@
defmodule BlockScoutWeb.AddressTransactionView do defmodule BlockScoutWeb.AddressTransactionView do
use BlockScoutWeb, :view use BlockScoutWeb, :view
alias BlockScoutWeb.AccessHelpers
alias Explorer.Chain.Address alias Explorer.Chain.Address
def format_current_filter(filter) do def format_current_filter(filter) do

@ -3,7 +3,7 @@ defmodule BlockScoutWeb.AddressView do
require Logger require Logger
alias BlockScoutWeb.LayoutView alias BlockScoutWeb.{AccessHelpers, LayoutView}
alias Explorer.Chain alias Explorer.Chain
alias Explorer.Chain.{Address, Hash, InternalTransaction, SmartContract, Token, TokenTransfer, Transaction, Wei} alias Explorer.Chain.{Address, Hash, InternalTransaction, SmartContract, Token, TokenTransfer, Transaction, Wei}
alias Explorer.Chain.Block.Reward alias Explorer.Chain.Block.Reward

@ -3,7 +3,7 @@ defmodule BlockScoutWeb.Tokens.OverviewView do
alias Explorer.Chain.{Address, SmartContract, Token} alias Explorer.Chain.{Address, SmartContract, Token}
alias BlockScoutWeb.{CurrencyHelpers, LayoutView} alias BlockScoutWeb.{AccessHelpers, CurrencyHelpers, LayoutView}
@tabs ["token-transfers", "token-holders", "read-contract", "inventory"] @tabs ["token-transfers", "token-holders", "read-contract", "inventory"]
@etherscan_token_link "https://etherscan.io/token/" @etherscan_token_link "https://etherscan.io/token/"

@ -1,4 +1,5 @@
defmodule BlockScoutWeb.TransactionInternalTransactionView do defmodule BlockScoutWeb.TransactionInternalTransactionView do
use BlockScoutWeb, :view use BlockScoutWeb, :view
@dialyzer :no_match @dialyzer :no_match
end end

@ -1,7 +1,7 @@
defmodule BlockScoutWeb.TransactionView do defmodule BlockScoutWeb.TransactionView do
use BlockScoutWeb, :view use BlockScoutWeb, :view
alias BlockScoutWeb.{AddressView, BlockView, TabHelpers} alias BlockScoutWeb.{AccessHelpers, AddressView, BlockView, TabHelpers}
alias BlockScoutWeb.Cldr.Number alias BlockScoutWeb.Cldr.Number
alias Explorer.{Chain, Repo} alias Explorer.{Chain, Repo}
alias Explorer.Chain.Block.Reward alias Explorer.Chain.Block.Reward

@ -139,9 +139,9 @@ msgstr ""
#: lib/block_scout_web/templates/address_transaction/index.html.eex:23 #: lib/block_scout_web/templates/address_transaction/index.html.eex:23
#: lib/block_scout_web/templates/layout/_network_selector.html.eex:21 #: lib/block_scout_web/templates/layout/_network_selector.html.eex:21
#: lib/block_scout_web/templates/layout/_topnav.html.eex:88 #: lib/block_scout_web/templates/layout/_topnav.html.eex:88
#: lib/block_scout_web/views/address_internal_transaction_view.ex:8 #: lib/block_scout_web/views/address_internal_transaction_view.ex:10
#: lib/block_scout_web/views/address_token_transfer_view.ex:8 #: 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:11
msgid "All" msgid "All"
msgstr "" msgstr ""
@ -252,7 +252,7 @@ msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/templates/address_token/index.html.eex:28 #: lib/block_scout_web/templates/address_token/index.html.eex:28
#: lib/block_scout_web/templates/address_transaction/index.html.eex:74 #: lib/block_scout_web/templates/address_transaction/index.html.eex:64
msgid "CSV" msgid "CSV"
msgstr "" msgstr ""
@ -703,12 +703,12 @@ msgid "Forked Blocks (Reorgs)"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:44 #: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:39
#: lib/block_scout_web/templates/address_token_transfer/index.html.eex:42 #: lib/block_scout_web/templates/address_token_transfer/index.html.eex:37
#: lib/block_scout_web/templates/address_transaction/index.html.eex:40 #: lib/block_scout_web/templates/address_transaction/index.html.eex:35
#: lib/block_scout_web/views/address_internal_transaction_view.ex:7 #: lib/block_scout_web/views/address_internal_transaction_view.ex:9
#: lib/block_scout_web/views/address_token_transfer_view.ex:7 #: 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:10
msgid "From" msgid "From"
msgstr "" msgstr ""
@ -801,7 +801,7 @@ msgid "There are no holders for this Token."
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:65 #: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:55
msgid "There are no internal transactions for this address." msgid "There are no internal transactions for this address."
msgstr "" msgstr ""
@ -817,7 +817,7 @@ msgid "There are no logs for this transaction."
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/templates/address_token_transfer/index.html.eex:60 #: lib/block_scout_web/templates/address_token_transfer/index.html.eex:50
msgid "There are no token transfers for this address." msgid "There are no token transfers for this address."
msgstr "" msgstr ""
@ -832,7 +832,7 @@ msgid "There are no tokens."
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/templates/address_transaction/index.html.eex:64 #: lib/block_scout_web/templates/address_transaction/index.html.eex:54
msgid "There are no transactions for this address." msgid "There are no transactions for this address."
msgstr "" msgstr ""
@ -856,9 +856,9 @@ msgstr ""
#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:33 #: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:33
#: lib/block_scout_web/templates/address_token_transfer/index.html.eex:31 #: lib/block_scout_web/templates/address_token_transfer/index.html.eex:31
#: lib/block_scout_web/templates/address_transaction/index.html.eex:29 #: lib/block_scout_web/templates/address_transaction/index.html.eex:29
#: lib/block_scout_web/views/address_internal_transaction_view.ex:6 #: lib/block_scout_web/views/address_internal_transaction_view.ex:8
#: lib/block_scout_web/views/address_token_transfer_view.ex:6 #: lib/block_scout_web/views/address_token_transfer_view.ex:8
#: lib/block_scout_web/views/address_transaction_view.ex:8 #: lib/block_scout_web/views/address_transaction_view.ex:9
msgid "To" msgid "To"
msgstr "" msgstr ""
@ -1302,11 +1302,11 @@ msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/templates/address_coin_balance/index.html.eex:36 #: lib/block_scout_web/templates/address_coin_balance/index.html.eex:36
#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:61 #: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:51
#: lib/block_scout_web/templates/address_logs/index.html.eex:21 #: lib/block_scout_web/templates/address_logs/index.html.eex:21
#: lib/block_scout_web/templates/address_token/index.html.eex:13 #: lib/block_scout_web/templates/address_token/index.html.eex:13
#: lib/block_scout_web/templates/address_token_transfer/index.html.eex:65 #: lib/block_scout_web/templates/address_token_transfer/index.html.eex:55
#: lib/block_scout_web/templates/address_transaction/index.html.eex:59 #: lib/block_scout_web/templates/address_transaction/index.html.eex:49
#: lib/block_scout_web/templates/address_validation/index.html.eex:22 #: lib/block_scout_web/templates/address_validation/index.html.eex:22
#: lib/block_scout_web/templates/block_transaction/index.html.eex:23 #: lib/block_scout_web/templates/block_transaction/index.html.eex:23
#: lib/block_scout_web/templates/chain/show.html.eex:154 #: lib/block_scout_web/templates/chain/show.html.eex:154

@ -139,9 +139,9 @@ msgstr ""
#: lib/block_scout_web/templates/address_transaction/index.html.eex:23 #: lib/block_scout_web/templates/address_transaction/index.html.eex:23
#: lib/block_scout_web/templates/layout/_network_selector.html.eex:21 #: lib/block_scout_web/templates/layout/_network_selector.html.eex:21
#: lib/block_scout_web/templates/layout/_topnav.html.eex:88 #: lib/block_scout_web/templates/layout/_topnav.html.eex:88
#: lib/block_scout_web/views/address_internal_transaction_view.ex:8 #: lib/block_scout_web/views/address_internal_transaction_view.ex:10
#: lib/block_scout_web/views/address_token_transfer_view.ex:8 #: 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:11
msgid "All" msgid "All"
msgstr "" msgstr ""
@ -252,7 +252,7 @@ msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/templates/address_token/index.html.eex:28 #: lib/block_scout_web/templates/address_token/index.html.eex:28
#: lib/block_scout_web/templates/address_transaction/index.html.eex:74 #: lib/block_scout_web/templates/address_transaction/index.html.eex:64
msgid "CSV" msgid "CSV"
msgstr "" msgstr ""
@ -703,12 +703,12 @@ msgid "Forked Blocks (Reorgs)"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:44 #: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:39
#: lib/block_scout_web/templates/address_token_transfer/index.html.eex:42 #: lib/block_scout_web/templates/address_token_transfer/index.html.eex:37
#: lib/block_scout_web/templates/address_transaction/index.html.eex:40 #: lib/block_scout_web/templates/address_transaction/index.html.eex:35
#: lib/block_scout_web/views/address_internal_transaction_view.ex:7 #: lib/block_scout_web/views/address_internal_transaction_view.ex:9
#: lib/block_scout_web/views/address_token_transfer_view.ex:7 #: 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:10
msgid "From" msgid "From"
msgstr "" msgstr ""
@ -801,7 +801,7 @@ msgid "There are no holders for this Token."
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:65 #: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:55
msgid "There are no internal transactions for this address." msgid "There are no internal transactions for this address."
msgstr "" msgstr ""
@ -817,7 +817,7 @@ msgid "There are no logs for this transaction."
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/templates/address_token_transfer/index.html.eex:60 #: lib/block_scout_web/templates/address_token_transfer/index.html.eex:50
msgid "There are no token transfers for this address." msgid "There are no token transfers for this address."
msgstr "" msgstr ""
@ -832,7 +832,7 @@ msgid "There are no tokens."
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/templates/address_transaction/index.html.eex:64 #: lib/block_scout_web/templates/address_transaction/index.html.eex:54
msgid "There are no transactions for this address." msgid "There are no transactions for this address."
msgstr "" msgstr ""
@ -856,9 +856,9 @@ msgstr ""
#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:33 #: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:33
#: lib/block_scout_web/templates/address_token_transfer/index.html.eex:31 #: lib/block_scout_web/templates/address_token_transfer/index.html.eex:31
#: lib/block_scout_web/templates/address_transaction/index.html.eex:29 #: lib/block_scout_web/templates/address_transaction/index.html.eex:29
#: lib/block_scout_web/views/address_internal_transaction_view.ex:6 #: lib/block_scout_web/views/address_internal_transaction_view.ex:8
#: lib/block_scout_web/views/address_token_transfer_view.ex:6 #: lib/block_scout_web/views/address_token_transfer_view.ex:8
#: lib/block_scout_web/views/address_transaction_view.ex:8 #: lib/block_scout_web/views/address_transaction_view.ex:9
msgid "To" msgid "To"
msgstr "" msgstr ""
@ -1302,11 +1302,11 @@ msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/templates/address_coin_balance/index.html.eex:36 #: lib/block_scout_web/templates/address_coin_balance/index.html.eex:36
#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:61 #: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:51
#: lib/block_scout_web/templates/address_logs/index.html.eex:21 #: lib/block_scout_web/templates/address_logs/index.html.eex:21
#: lib/block_scout_web/templates/address_token/index.html.eex:13 #: lib/block_scout_web/templates/address_token/index.html.eex:13
#: lib/block_scout_web/templates/address_token_transfer/index.html.eex:65 #: lib/block_scout_web/templates/address_token_transfer/index.html.eex:55
#: lib/block_scout_web/templates/address_transaction/index.html.eex:59 #: lib/block_scout_web/templates/address_transaction/index.html.eex:49
#: lib/block_scout_web/templates/address_validation/index.html.eex:22 #: lib/block_scout_web/templates/address_validation/index.html.eex:22
#: lib/block_scout_web/templates/block_transaction/index.html.eex:23 #: lib/block_scout_web/templates/block_transaction/index.html.eex:23
#: lib/block_scout_web/templates/chain/show.html.eex:154 #: lib/block_scout_web/templates/chain/show.html.eex:154

Loading…
Cancel
Save