diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/address_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/address_controller.ex index 1ca5db5dcd..43418c135d 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/address_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/address_controller.ex @@ -16,7 +16,8 @@ defmodule BlockScoutWeb.API.V2.AddressController do alias BlockScoutWeb.AccessHelper alias BlockScoutWeb.API.V2.{BlockView, TransactionView, WithdrawalView} - alias Explorer.{Chain, Market} + alias Explorer.{Chain, Market, Repo} + alias Explorer.Chain.Address alias Explorer.Chain.Address.Counters alias Explorer.Chain.Token.Instance alias Indexer.Fetcher.{CoinBalanceOnDemand, TokenBalanceOnDemand} @@ -46,15 +47,18 @@ defmodule BlockScoutWeb.API.V2.AddressController do @address_options [ necessity_by_association: %{ - :contracts_creation_internal_transaction => :optional, :names => :optional, - :smart_contract => :optional, - :token => :optional, - :contracts_creation_transaction => :optional + :token => :optional }, api?: true ] + @contract_address_preloads [ + :smart_contract, + :contracts_creation_internal_transaction, + :contracts_creation_transaction + ] + @nft_necessity_by_association [ necessity_by_association: %{ :token => :optional @@ -66,12 +70,13 @@ defmodule BlockScoutWeb.API.V2.AddressController do action_fallback(BlockScoutWeb.API.V2.FallbackController) def address(conn, %{"address_hash_param" => address_hash_string} = params) do - with {:ok, _address_hash, address} <- validate_address(address_hash_string, params, @address_options) do - CoinBalanceOnDemand.trigger_fetch(address) + with {:ok, _address_hash, address} <- validate_address(address_hash_string, params, @address_options), + fully_preloaded_address <- maybe_preload_smart_contract_associations(address) do + CoinBalanceOnDemand.trigger_fetch(fully_preloaded_address) conn |> put_status(200) - |> render(:address, %{address: address}) + |> render(:address, %{address: fully_preloaded_address}) end end @@ -477,4 +482,9 @@ defmodule BlockScoutWeb.API.V2.AddressController do {:ok, address_hash, address} end end + + defp maybe_preload_smart_contract_associations(%Address{contract_code: nil} = address), do: address + + defp maybe_preload_smart_contract_associations(%Address{contract_code: _} = address), + do: Repo.replica().preload(address, @contract_address_preloads) end diff --git a/apps/block_scout_web/lib/block_scout_web/views/address_view.ex b/apps/block_scout_web/lib/block_scout_web/views/address_view.ex index 41ebf80976..3098dfc096 100644 --- a/apps/block_scout_web/lib/block_scout_web/views/address_view.ex +++ b/apps/block_scout_web/lib/block_scout_web/views/address_view.ex @@ -258,7 +258,7 @@ defmodule BlockScoutWeb.AddressView do Enum.any?(address.smart_contract.abi || [], &is_read_function?(&1)) end - def smart_contract_with_read_only_functions?(%Address{smart_contract: nil}), do: false + def smart_contract_with_read_only_functions?(%Address{smart_contract: _}), do: false def is_read_function?(function), do: Helper.queriable_method?(function) || Helper.read_with_wallet_method?(function) @@ -268,7 +268,7 @@ defmodule BlockScoutWeb.AddressView do SmartContract.proxy_contract?(smart_contract, options) end - def smart_contract_is_proxy?(%Address{smart_contract: nil}, _), do: false + def smart_contract_is_proxy?(%Address{smart_contract: _}, _), do: false def smart_contract_with_write_functions?(%Address{smart_contract: %SmartContract{}} = address) do !contract_interaction_disabled?() && @@ -278,7 +278,7 @@ defmodule BlockScoutWeb.AddressView do ) end - def smart_contract_with_write_functions?(%Address{smart_contract: nil}), do: false + def smart_contract_with_write_functions?(%Address{smart_contract: _}), do: false def has_decompiled_code?(address) do address.has_decompiled_code? ||