Merge pull request #4621 from blockscout/np-add-beacon-slot-proxy

Add beacon contract address storage slot for proxy
pull/4654/head
Victor Baranov 3 years ago committed by GitHub
commit 2cbfe01ec6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      CHANGELOG.md
  2. 33
      apps/block_scout_web/test/block_scout_web/controllers/address_read_contract_controller_test.exs
  3. 33
      apps/block_scout_web/test/block_scout_web/controllers/address_read_proxy_controller_test.exs
  4. 33
      apps/block_scout_web/test/block_scout_web/controllers/address_write_contract_controller_test.exs
  5. 33
      apps/block_scout_web/test/block_scout_web/controllers/address_write_proxy_controller_test.exs
  6. 33
      apps/block_scout_web/test/block_scout_web/controllers/smart_contract_controller_test.exs
  7. 43
      apps/explorer/lib/explorer/chain.ex

@ -1,6 +1,7 @@
## Current
### Features
- [#4621](https://github.com/blockscout/blockscout/pull/4621) - Add beacon contract address slot for proxy
- [#4625](https://github.com/blockscout/blockscout/pull/4625) - Contract address page: Add implementation link to the overview of proxy contracts
- [#4624](https://github.com/blockscout/blockscout/pull/4624) - Support HTML tags in alert message
- [#4608](https://github.com/blockscout/blockscout/pull/4608), [#4622](https://github.com/blockscout/blockscout/pull/4622) - Block Details page: Improved style of transactions button

@ -84,16 +84,29 @@ defmodule BlockScoutWeb.AddressReadContractControllerTest do
end
def get_eip1967_implementation do
expect(EthereumJSONRPC.Mox, :json_rpc, fn %{
id: 0,
method: "eth_getStorageAt",
params: [
_,
"0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc",
"latest"
]
},
_options ->
EthereumJSONRPC.Mox
|> expect(:json_rpc, fn %{
id: 0,
method: "eth_getStorageAt",
params: [
_,
"0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc",
"latest"
]
},
_options ->
{:ok, "0x0000000000000000000000000000000000000000000000000000000000000000"}
end)
|> expect(:json_rpc, fn %{
id: 0,
method: "eth_getStorageAt",
params: [
_,
"0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50",
"latest"
]
},
_options ->
{:ok, "0x0000000000000000000000000000000000000000000000000000000000000000"}
end)
end

@ -81,16 +81,29 @@ defmodule BlockScoutWeb.AddressReadProxyControllerTest do
end
def get_eip1967_implementation do
expect(EthereumJSONRPC.Mox, :json_rpc, fn %{
id: 0,
method: "eth_getStorageAt",
params: [
_,
"0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc",
"latest"
]
},
_options ->
EthereumJSONRPC.Mox
|> expect(:json_rpc, fn %{
id: 0,
method: "eth_getStorageAt",
params: [
_,
"0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc",
"latest"
]
},
_options ->
{:ok, "0x0000000000000000000000000000000000000000000000000000000000000000"}
end)
|> expect(:json_rpc, fn %{
id: 0,
method: "eth_getStorageAt",
params: [
_,
"0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50",
"latest"
]
},
_options ->
{:ok, "0x0000000000000000000000000000000000000000000000000000000000000000"}
end)
end

@ -85,16 +85,29 @@ defmodule BlockScoutWeb.AddressWriteContractControllerTest do
end
def get_eip1967_implementation do
expect(EthereumJSONRPC.Mox, :json_rpc, fn %{
id: 0,
method: "eth_getStorageAt",
params: [
_,
"0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc",
"latest"
]
},
_options ->
EthereumJSONRPC.Mox
|> expect(:json_rpc, fn %{
id: 0,
method: "eth_getStorageAt",
params: [
_,
"0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc",
"latest"
]
},
_options ->
{:ok, "0x0000000000000000000000000000000000000000000000000000000000000000"}
end)
|> expect(:json_rpc, fn %{
id: 0,
method: "eth_getStorageAt",
params: [
_,
"0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50",
"latest"
]
},
_options ->
{:ok, "0x0000000000000000000000000000000000000000000000000000000000000000"}
end)
end

@ -83,16 +83,29 @@ defmodule BlockScoutWeb.AddressWriteProxyControllerTest do
end
def get_eip1967_implementation do
expect(EthereumJSONRPC.Mox, :json_rpc, fn %{
id: 0,
method: "eth_getStorageAt",
params: [
_,
"0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc",
"latest"
]
},
_options ->
EthereumJSONRPC.Mox
|> expect(:json_rpc, fn %{
id: 0,
method: "eth_getStorageAt",
params: [
_,
"0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc",
"latest"
]
},
_options ->
{:ok, "0x0000000000000000000000000000000000000000000000000000000000000000"}
end)
|> expect(:json_rpc, fn %{
id: 0,
method: "eth_getStorageAt",
params: [
_,
"0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50",
"latest"
]
},
_options ->
{:ok, "0x0000000000000000000000000000000000000000000000000000000000000000"}
end)
end

@ -292,16 +292,29 @@ defmodule BlockScoutWeb.SmartContractControllerTest do
end
def get_eip1967_implementation do
expect(EthereumJSONRPC.Mox, :json_rpc, fn %{
id: 0,
method: "eth_getStorageAt",
params: [
_,
"0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc",
"latest"
]
},
_options ->
EthereumJSONRPC.Mox
|> expect(:json_rpc, fn %{
id: 0,
method: "eth_getStorageAt",
params: [
_,
"0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc",
"latest"
]
},
_options ->
{:ok, "0x0000000000000000000000000000000000000000000000000000000000000000"}
end)
|> expect(:json_rpc, fn %{
id: 0,
method: "eth_getStorageAt",
params: [
_,
"0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50",
"latest"
]
},
_options ->
{:ok, "0x0000000000000000000000000000000000000000000000000000000000000000"}
end)
end

@ -6575,17 +6575,40 @@ defmodule Explorer.Chain do
json_rpc_named_arguments = Application.get_env(:explorer, :json_rpc_named_arguments)
# https://eips.ethereum.org/EIPS/eip-1967
eip_1967_implementation_storage_pointer = "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc"
storage_slot_logic_contract_address = "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc"
storage_slot_beacon_contract_address = "0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50"
{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, implementation_address} =
Contract.eth_get_storage_at_request(
proxy_address_hash,
eip_1967_implementation_storage_pointer,
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
)
abi_decode_address_output(implementation_address)
{:ok, implementation_logic_address} ->
{:ok, implementation_logic_address}
{:error, _} ->
{:ok, "0x"}
end
abi_decode_address_output(if status == :ok, do: implementation_address, else: "0x")
end
defp get_implementation_address_hash_basic(proxy_address_hash, abi) do
@ -6640,6 +6663,8 @@ defmodule Explorer.Chain do
defp abi_decode_address_output(address) when is_nil(address), do: nil
defp abi_decode_address_output("0x"), do: @burn_address_hash_str
defp abi_decode_address_output(address) do
if String.length(address) > 42 do
"0x" <> String.slice(address, -40, 40)

Loading…
Cancel
Save