diff --git a/CHANGELOG.md b/CHANGELOG.md index c7f982fc03..4415485652 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,7 @@ - [#5786](https://github.com/blockscout/blockscout/pull/5786) - Replace `current_path` with `Controller.current_full_path` in two controllers - [#5948](https://github.com/blockscout/blockscout/pull/5948) - Fix unexpected messages in `CoinBalanceOnDemand` - [#6013](https://github.com/blockscout/blockscout/pull/6013) - Fix ERC-1155 tokens fetching +- [#6043](https://github.com/blockscout/blockscout/pull/6043) - Fix token instance fetching ### Chore diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/tokens/instance/holder_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/tokens/instance/holder_controller.ex index 1712775ece..3ee291f43b 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/tokens/instance/holder_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/tokens/instance/holder_controller.ex @@ -56,12 +56,12 @@ defmodule BlockScoutWeb.Tokens.Instance.HolderController do with {:ok, hash} <- Chain.string_to_address_hash(token_address_hash), {:ok, token} <- Chain.token_from_address_hash(hash, options), - {:ok, token_transfer} <- - Chain.erc721_token_instance_from_token_id_and_token_address(token_id, hash) do + {:ok, token_instance} <- + Chain.erc721_or_erc1155_token_instance_from_token_id_and_token_address(token_id, hash) do render( conn, "index.html", - token_instance: token_transfer, + token_instance: %{instance: token_instance, token_id: Decimal.new(token_id)}, current_path: Controller.current_full_path(conn), token: Market.add_price(token), total_token_transfers: Chain.count_token_transfers_from_token_hash_and_token_id(hash, token_id) diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/tokens/instance/metadata_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/tokens/instance/metadata_controller.ex index e075e86cff..b404cc91b8 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/tokens/instance/metadata_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/tokens/instance/metadata_controller.ex @@ -9,13 +9,13 @@ defmodule BlockScoutWeb.Tokens.Instance.MetadataController do with {:ok, hash} <- Chain.string_to_address_hash(token_address_hash), {:ok, token} <- Chain.token_from_address_hash(hash, options), - {:ok, token_transfer} <- - Chain.erc721_token_instance_from_token_id_and_token_address(token_id, hash) do - if token_transfer.instance && token_transfer.instance.metadata do + {:ok, token_instance} <- + Chain.erc721_or_erc1155_token_instance_from_token_id_and_token_address(token_id, hash) do + if token_instance.metadata do render( conn, "index.html", - token_instance: token_transfer, + token_instance: %{instance: token_instance, token_id: Decimal.new(token_id)}, current_path: Controller.current_full_path(conn), token: Market.add_price(token), total_token_transfers: Chain.count_token_transfers_from_token_hash_and_token_id(hash, token_id) diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/tokens/instance/transfer_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/tokens/instance/transfer_controller.ex index 3aa9c61878..1e92527d0f 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/tokens/instance/transfer_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/tokens/instance/transfer_controller.ex @@ -58,12 +58,12 @@ defmodule BlockScoutWeb.Tokens.Instance.TransferController do with {:ok, hash} <- Chain.string_to_address_hash(token_address_hash), {:ok, token} <- Chain.token_from_address_hash(hash, options), - {:ok, token_transfer} <- + {:ok, token_instance} <- Chain.erc721_or_erc1155_token_instance_from_token_id_and_token_address(token_id, hash) do render( conn, "index.html", - token_instance: token_transfer, + token_instance: %{instance: token_instance, token_id: Decimal.new(token_id)}, current_path: Controller.current_full_path(conn), token: Market.add_price(token), total_token_transfers: Chain.count_token_transfers_from_token_hash_and_token_id(hash, token_id) diff --git a/apps/block_scout_web/test/block_scout_web/controllers/tokens/instance/transfer_controller_test.exs b/apps/block_scout_web/test/block_scout_web/controllers/tokens/instance/transfer_controller_test.exs index ee04094cc9..8f4a49cabb 100644 --- a/apps/block_scout_web/test/block_scout_web/controllers/tokens/instance/transfer_controller_test.exs +++ b/apps/block_scout_web/test/block_scout_web/controllers/tokens/instance/transfer_controller_test.exs @@ -2,43 +2,29 @@ defmodule BlockScoutWeb.Tokens.Instance.TransferControllerTest do use BlockScoutWeb.ConnCase, async: false describe "GET token-transfers/2" do - test "works for ERC-721 tokens", %{conn: conn} do + test "fetches the instance", %{conn: conn} do contract_address = insert(:address) insert(:token, contract_address: contract_address) - token_id = 10 + contract_address_hash = contract_address.hash - %{log_index: log_index} = - insert(:token_transfer, - from_address: contract_address, - token_contract_address: contract_address, - token_id: token_id - ) + token_id = Decimal.new(10) - conn = get(conn, "/token/#{contract_address.hash}/instance/#{token_id}/token-transfers") + insert(:token_instance, + token_contract_address_hash: contract_address_hash, + token_id: token_id + ) - assert %{assigns: %{token_instance: %{log_index: ^log_index}}} = conn - end - - test "works for ERC-1155 tokens", %{conn: conn} do - contract_address = insert(:address) - - insert(:token, contract_address: contract_address) - - token_id = 10 - - %{log_index: log_index} = - insert(:token_transfer, - from_address: contract_address, - token_contract_address: contract_address, - token_id: nil, - token_ids: [token_id] - ) - - conn = get(conn, "/token/#{contract_address.hash}/instance/#{token_id}/token-transfers") + conn = get(conn, "/token/#{contract_address_hash}/instance/#{token_id}/token-transfers") - assert %{assigns: %{token_instance: %{log_index: ^log_index}}} = conn + assert %{ + assigns: %{ + token_instance: %{ + instance: %{token_contract_address_hash: ^contract_address_hash, token_id: ^token_id} + } + } + } = conn end end end diff --git a/apps/explorer/lib/explorer/chain.ex b/apps/explorer/lib/explorer/chain.ex index 8c121738bd..7b0c65c263 100644 --- a/apps/explorer/lib/explorer/chain.ex +++ b/apps/explorer/lib/explorer/chain.ex @@ -4882,20 +4882,10 @@ defmodule Explorer.Chain do end @spec erc721_or_erc1155_token_instance_from_token_id_and_token_address(binary(), Hash.Address.t()) :: - {:ok, TokenTransfer.t()} | {:error, :not_found} + {:ok, Instance.t()} | {:error, :not_found} def erc721_or_erc1155_token_instance_from_token_id_and_token_address(token_id, token_contract_address) do query = - from(tt in TokenTransfer, - left_join: instance in Instance, - on: - tt.token_contract_address_hash == instance.token_contract_address_hash and - (tt.token_id == instance.token_id or fragment("? @> ARRAY[?::decimal]", tt.token_ids, instance.token_id)), - where: - tt.token_contract_address_hash == ^token_contract_address and - (tt.token_id == ^token_id or fragment("? @> ARRAY[?::decimal]", tt.token_ids, ^Decimal.new(token_id))), - limit: 1, - select: %{tt | instance: instance} - ) + from(i in Instance, where: i.token_contract_address_hash == ^token_contract_address and i.token_id == ^token_id) case Repo.one(query) do nil -> {:error, :not_found} diff --git a/apps/explorer/lib/explorer/chain/token/instance.ex b/apps/explorer/lib/explorer/chain/token/instance.ex index 1a6883492b..005ee3a2c0 100644 --- a/apps/explorer/lib/explorer/chain/token/instance.ex +++ b/apps/explorer/lib/explorer/chain/token/instance.ex @@ -18,7 +18,7 @@ defmodule Explorer.Chain.Token.Instance do @type t :: %Instance{ token_id: non_neg_integer(), token_contract_address_hash: Hash.Address.t(), - metadata: map(), + metadata: map() | nil, error: String.t() }