diff --git a/CHANGELOG.md b/CHANGELOG.md index 399b315634ae..d0b106a3ca4c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ ## Current ### Features +- [#4807](https://github.com/blockscout/blockscout/pull/4807) - Added support for BeaconProxy pattern - [#4777](https://github.com/blockscout/blockscout/pull/4777), [#4791](https://github.com/blockscout/blockscout/pull/4791), [#4799](https://github.com/blockscout/blockscout/pull/4799), [#4847](https://github.com/blockscout/blockscout/pull/4847) - Added decoding revert reason - [#4776](https://github.com/blockscout/blockscout/pull/4776) - Added view for unsuccessfully fetched values from read functions - [#4761](https://github.com/blockscout/blockscout/pull/4761) - ERC-1155 support diff --git a/apps/explorer/lib/explorer/chain.ex b/apps/explorer/lib/explorer/chain.ex index 28137e728c49..2f301fa14b2c 100644 --- a/apps/explorer/lib/explorer/chain.ex +++ b/apps/explorer/lib/explorer/chain.ex @@ -6790,30 +6790,17 @@ defmodule Explorer.Chain do # https://eips.ethereum.org/EIPS/eip-1967 storage_slot_logic_contract_address = "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" - storage_slot_beacon_contract_address = "0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50" - {status, implementation_address} = + {_status, implementation_address} = case Contract.eth_get_storage_at_request( proxy_address_hash, storage_slot_logic_contract_address, nil, json_rpc_named_arguments ) do - {:ok, "0x"} -> - Contract.eth_get_storage_at_request( - proxy_address_hash, - storage_slot_beacon_contract_address, - nil, - json_rpc_named_arguments - ) - - {:ok, "0x0000000000000000000000000000000000000000000000000000000000000000"} -> - Contract.eth_get_storage_at_request( - proxy_address_hash, - storage_slot_beacon_contract_address, - nil, - json_rpc_named_arguments - ) + {:ok, empty_address} + when empty_address in ["0x", "0x0000000000000000000000000000000000000000000000000000000000000000"] -> + fetch_beacon_proxy_implementation(proxy_address_hash, json_rpc_named_arguments) {:ok, implementation_logic_address} -> {:ok, implementation_logic_address} @@ -6822,7 +6809,49 @@ defmodule Explorer.Chain do {:ok, "0x"} end - abi_decode_address_output(if status == :ok, do: implementation_address, else: "0x") + abi_decode_address_output(implementation_address) + end + + # changes requested by https://github.com/blockscout/blockscout/issues/4770 + # for support BeaconProxy pattern + defp fetch_beacon_proxy_implementation(proxy_address_hash, json_rpc_named_arguments) do + # https://eips.ethereum.org/EIPS/eip-1967 + storage_slot_beacon_contract_address = "0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50" + + implementation_method_abi = [ + %{ + "type" => "function", + "stateMutability" => "view", + "outputs" => [%{"type" => "address", "name" => "", "internalType" => "address"}], + "name" => "implementation", + "inputs" => [] + } + ] + + case Contract.eth_get_storage_at_request( + proxy_address_hash, + storage_slot_beacon_contract_address, + nil, + json_rpc_named_arguments + ) do + {:ok, empty_address} + when empty_address in ["0x", "0x0000000000000000000000000000000000000000000000000000000000000000"] -> + {:ok, "0x"} + + {:ok, beacon_contract_address} -> + case beacon_contract_address + |> abi_decode_address_output() + |> get_implementation_address_hash_basic(implementation_method_abi) do + <> -> + {:ok, implementation_address} + + _ -> + {:ok, beacon_contract_address} + end + + {:error, _} -> + {:ok, "0x"} + end end defp get_implementation_address_hash_basic(proxy_address_hash, abi) do @@ -6880,11 +6909,11 @@ defmodule Explorer.Chain do end) end - defp abi_decode_address_output(address) when is_nil(address), do: nil + defp abi_decode_address_output(nil), do: nil defp abi_decode_address_output("0x"), do: @burn_address_hash_str - defp abi_decode_address_output(address) do + defp abi_decode_address_output(address) when is_binary(address) do if String.length(address) > 42 do "0x" <> String.slice(address, -40, 40) else @@ -6892,6 +6921,8 @@ defmodule Explorer.Chain do end end + defp abi_decode_address_output(_), do: nil + defp address_to_hex(address) do if address do if String.starts_with?(address, "0x") do