Merge branch 'master' into feature/#1893-new-pagination-view

pull/1928/head
Victor Baranov 6 years ago committed by GitHub
commit f9a3f1f4de
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      .dialyzer-ignore
  2. 2
      CHANGELOG.md
  3. 60
      apps/block_scout_web/config/config.exs
  4. 21
      apps/block_scout_web/lib/block_scout_web/controllers/api/rpc/contract_controller.ex
  5. 82
      apps/block_scout_web/lib/block_scout_web/etherscan.ex
  6. 4
      apps/block_scout_web/lib/block_scout_web/templates/layout/_footer.html.eex
  7. 6
      apps/block_scout_web/lib/block_scout_web/templates/layout/_topnav.html.eex
  8. 54
      apps/block_scout_web/lib/block_scout_web/views/api/rpc/contract_view.ex
  9. 98
      apps/block_scout_web/lib/block_scout_web/views/layout_view.ex
  10. 32
      apps/block_scout_web/test/block_scout_web/controllers/api/rpc/contract_controller_test.exs
  11. 119
      apps/block_scout_web/test/block_scout_web/views/layout_view_test.exs
  12. 8
      apps/explorer/lib/explorer/chain.ex
  13. 2
      apps/explorer/lib/explorer/chain/address.ex

@ -4,3 +4,4 @@
apps/ethereum_jsonrpc/lib/ethereum_jsonrpc.ex:400: Function timestamp_to_datetime/1 has no local return
apps/explorer/lib/explorer/repo/prometheus_logger.ex:8: Function microseconds_time/1 has no local return
apps/explorer/lib/explorer/repo/prometheus_logger.ex:8: The call 'Elixir.System':convert_time_unit(__@1::any(),'native','microseconds') breaks the contract (integer(),time_unit() | 'native',time_unit() | 'native') -> integer()
apps/block_scout_web/lib/block_scout_web/views/layout_view.ex:162: The call 'Elixir.Poison.Parser':'parse!'(any(),#{'keys':='atoms!'}) will never return since the success typing is (binary() | maybe_improper_list(binary() | maybe_improper_list(any(),binary() | []) | byte(),binary() | []),[{atom(),_}]) -> 'false' | 'nil' | 'true' | binary() | ['false' | 'nil' | 'true' | binary() | [any()] | number() | map()] | number() | map() and the contract is (iodata(),'Elixir.Keyword':t()) -> t()

@ -14,6 +14,7 @@
- [#1806](https://github.com/poanetwork/blockscout/pull/1806) - verify contracts with a post request
- [#1857](https://github.com/poanetwork/blockscout/pull/1857) - Re-implement Geth JS internal transaction tracer in Elixir
- [#1859](https://github.com/poanetwork/blockscout/pull/1859) - feat: show raw transaction traces
- [#1920](https://github.com/poanetwork/blockscout/pull/1920) - fix: remove source code fields from list endpoint
- [#1876](https://github.com/poanetwork/blockscout/pull/1876) - async calculate a count of blocks
### Fixes
@ -40,6 +41,7 @@
- [#1814](https://github.com/poanetwork/blockscout/pull/1814) - Clear build artefacts script
- [#1837](https://github.com/poanetwork/blockscout/pull/1837) - Add -f flag to clear_build.sh script delete static folder
- [#1900](https://github.com/poanetwork/blockscout/pull/1900) - SUPPORTED_CHAINS ENV var
- [#1892](https://github.com/poanetwork/blockscout/pull/1892) - Remove temporary worker modules
## 1.3.10-beta

@ -28,65 +28,7 @@ config :block_scout_web,
"EtherChain" => "https://www.etherchain.org/",
"Bloxy" => "https://bloxy.info/"
},
other_networks: [
%{
title: "POA Core",
url: "https://blockscout.com/poa/core"
},
%{
title: "POA Sokol",
url: "https://blockscout.com/poa/sokol",
test_net?: true
},
%{
title: "xDai Chain",
url: "https://blockscout.com/poa/dai"
},
%{
title: "Ethereum Mainnet",
url: "https://blockscout.com/eth/mainnet"
},
%{
title: "Kovan Testnet",
url: "https://blockscout.com/eth/kovan",
test_net?: true
},
%{
title: "Ropsten Testnet",
url: "https://blockscout.com/eth/ropsten",
test_net?: true
},
%{
title: "Goerli Testnet",
url: "https://blockscout.com/eth/goerli",
test_net?: true
},
%{
title: "Rinkeby Testnet",
url: "https://blockscout.com/eth/rinkeby",
test_net?: true
},
%{
title: "Ethereum Classic",
url: "https://blockscout.com/etc/mainnet",
other?: true
},
%{
title: "Aerum Mainnet",
url: "https://blockscout.com/aerum/mainnet",
other?: true
},
%{
title: "Callisto Mainnet",
url: "https://blockscout.com/callisto/mainnet",
other?: true
},
%{
title: "RSK Mainnet",
url: "https://blockscout.com/rsk/mainnet",
other?: true
}
]
other_networks: System.get_env("SUPPORTED_CHAINS")
config :block_scout_web, BlockScoutWeb.Counters.BlocksIndexedCounter, enabled: true

@ -8,16 +8,21 @@ defmodule BlockScoutWeb.API.RPC.ContractController do
def verify(conn, %{"addressHash" => address_hash} = params) do
with {:params, {:ok, fetched_params}} <- {:params, fetch_verify_params(params)},
{:format, {:ok, casted_address_hash}} <- to_address_hash(address_hash),
{:params, external_libraries} <-
{:params, fetch_external_libraries(params)},
{:publish, {:ok, smart_contract}} <-
{:publish, Publisher.publish(address_hash, fetched_params, external_libraries)},
preloaded_smart_contract <- SmartContract.preload_decompiled_smart_contract(smart_contract) do
render(conn, :verify, %{contract: preloaded_smart_contract, address_hash: address_hash})
{:publish, {:ok, _}} <-
{:publish, Publisher.publish(address_hash, fetched_params, external_libraries)} do
address = Chain.address_hash_to_address_with_source_code(casted_address_hash)
render(conn, :verify, %{contract: address})
else
{:publish, _} ->
render(conn, :error, error: "Something went wrong while publishing the contract.")
{:format, :error} ->
render(conn, :error, error: "Invalid address hash")
{:params, {:error, error}} ->
render(conn, :error, error: error)
end
@ -63,11 +68,11 @@ defmodule BlockScoutWeb.API.RPC.ContractController do
def getsourcecode(conn, params) do
with {:address_param, {:ok, address_param}} <- fetch_address(params),
{:format, {:ok, address_hash}} <- to_address_hash(address_param),
{:contract, {:ok, contract}} <- to_smart_contract(address_hash) do
{:format, {:ok, address_hash}} <- to_address_hash(address_param) do
address = Chain.address_hash_to_address_with_source_code(address_hash)
render(conn, :getsourcecode, %{
contract: contract,
address_hash: address_hash
contract: address
})
else
{:address_param, :error} ->

@ -825,48 +825,11 @@ defmodule BlockScoutWeb.Etherscan do
name: "Contract",
fields: %{
"Address" => @address_hash_type,
"SourceCode" => %{
type: "contract source code",
definition: "The contract's source code.",
example: """
"pragma solidity >0.4.24;
contract Test {
constructor() public { b = hex"12345678901234567890123456789012"; }
event Event(uint indexed a, bytes32 b);
event Event2(uint indexed a, bytes32 b);
function foo(uint a) public { emit Event(a, b); }
bytes32 b;
}"
"""
},
"DecompilerVersion" => %{
type: "decompiler version",
definition: "When decompiled source code is present, the decompiler version with which it was generated.",
example: "decompiler.version"
},
"DecompiledSourceCode" => %{
type: "contract decompiled source code",
definition: "The contract's decompiled source code.",
example: """
const name() = 'CryptoKitties'
const GEN0_STARTING_PRICE() = 10^16
const GEN0_AUCTION_DURATION() = 86400
const GEN0_CREATION_LIMIT() = 45000
const symbol() = 'CK'
const PROMO_CREATION_LIMIT() = 5000
def storage:
ceoAddress is addr # mask(160, 0) at storage #0
cfoAddress is addr # mask(160, 0) at storage #1
stor1.768 is uint16 => uint256 # mask(256, 768) at storage #1
cooAddress is addr # mask(160, 0) at storage #2
stor2.0 is uint256 => uint256 # mask(256, 0) at storage #2
paused is uint8 # mask(8, 160) at storage #2
stor2.256 is uint256 => uint256 # mask(256, 256) at storage #2
stor3 is uint32 #
...<continues>
"""
},
"ABI" => %{
type: "ABI",
definition: "JSON string for the contract's Application Binary Interface (ABI)",
@ -899,6 +862,49 @@ defmodule BlockScoutWeb.Etherscan do
}
}
@contract_source_code_type %{
type: "contract source code",
definition: "The contract's source code.",
example: """
"pragma solidity >0.4.24;
contract Test {
constructor() public { b = hex"12345678901234567890123456789012"; }
event Event(uint indexed a, bytes32 b);
event Event2(uint indexed a, bytes32 b);
function foo(uint a) public { emit Event(a, b); }
bytes32 b;
}"
"""
}
@contract_decompiled_source_code_type %{
type: "contract decompiled source code",
definition: "The contract's decompiled source code.",
example: """
const name() = 'CryptoKitties'
const GEN0_STARTING_PRICE() = 10^16
const GEN0_AUCTION_DURATION() = 86400
const GEN0_CREATION_LIMIT() = 45000
const symbol() = 'CK'
const PROMO_CREATION_LIMIT() = 5000
def storage:
ceoAddress is addr # mask(160, 0) at storage #0
cfoAddress is addr # mask(160, 0) at storage #1
stor1.768 is uint16 => uint256 # mask(256, 768) at storage #1
cooAddress is addr # mask(160, 0) at storage #2
stor2.0 is uint256 => uint256 # mask(256, 0) at storage #2
paused is uint8 # mask(8, 160) at storage #2
stor2.256 is uint256 => uint256 # mask(256, 256) at storage #2
stor3 is uint32 #
...<continues>
"""
}
@contract_with_sourcecode_model @contract_model
|> put_in([:fields, "SourceCode"], @contract_source_code_type)
|> put_in([:fields, "DecompiledSourceCode"], @contract_decompiled_source_code_type)
@transaction_receipt_status_model %{
name: "TransactionReceiptStatus",
fields: %{
@ -1971,7 +1977,7 @@ defmodule BlockScoutWeb.Etherscan do
message: @message_type,
result: %{
type: "array",
array_type: @contract_model
array_type: @contract_with_sourcecode_model
}
}
}

@ -37,7 +37,7 @@
<li><a href="https://forum.poa.network/c/blockscout" rel="noreferrer" class="footer-link"><%= gettext("Support") %></a></li>
</ul>
</div>
<% main_nets = main_nets() %>
<% main_nets = main_nets(other_networks()) %>
<%= unless Enum.empty?(main_nets) do %>
<div class="col-md-<%= col_size %> footer-list">
@ -50,7 +50,7 @@
</div>
<% end %>
<% test_nets = test_nets() %>
<% test_nets = test_nets(other_networks()) %>
<%= unless Enum.empty?(test_nets) do %>
<div class="col-md-<%= col_size %> footer-list">

@ -85,15 +85,15 @@
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
<a class="dropdown-item header division">Mainnets</a>
<%= for %{url: url, title: title} <- head_main_nets() do %>
<%= for %{url: url, title: title} <- dropdown_head_main_nets() do %>
<a class="dropdown-item" href="<%= url%>"><%= title %></a>
<% end %>
<a class="dropdown-item header division">Testnets</a>
<%= for %{url: url, title: title} <- test_nets() do %>
<%= for %{url: url, title: title} <- test_nets(dropdown_nets()) do %>
<a class="dropdown-item" href="<%= url%>"><%= title %></a>
<% end %>
<a class="dropdown-item header division">Other networks</a>
<%= for %{url: url, title: title} <- other_nets() do %>
<%= for %{url: url, title: title} <- dropdown_other_nets() do %>
<a class="dropdown-item" href="<%= url%>"><%= title %></a>
<% end %>
</div>

@ -14,43 +14,63 @@ defmodule BlockScoutWeb.API.RPC.ContractView do
RPCView.render("show.json", data: Jason.encode!(abi))
end
def render("getsourcecode.json", %{contract: contract, address_hash: address_hash}) do
RPCView.render("show.json", data: [prepare_source_code_contract(contract, address_hash)])
def render("getsourcecode.json", %{contract: contract}) do
RPCView.render("show.json", data: [prepare_source_code_contract(contract)])
end
def render("error.json", assigns) do
RPCView.render("error.json", assigns)
end
def render("verify.json", %{contract: contract, address_hash: address_hash}) do
RPCView.render("show.json", data: prepare_source_code_contract(contract, address_hash))
def render("verify.json", %{contract: contract}) do
RPCView.render("show.json", data: prepare_source_code_contract(contract))
end
defp prepare_source_code_contract(nil, address_hash) do
defp prepare_source_code_contract(nil) do
%{
"Address" => to_string(address_hash),
"Address" => "",
"SourceCode" => "",
"ABI" => "Contract source code not verified",
"ContractName" => "",
"CompilerVersion" => "",
"DecompiledSourceCode" => "",
"DecompilerVersion" => "",
"DecompilerVersion" => decompiler_version(nil),
"OptimizationUsed" => ""
}
end
defp prepare_source_code_contract(contract, _) do
decompiled_smart_contract = latest_decompiled_smart_contract(contract.decompiled_smart_contracts)
defp prepare_source_code_contract(address) do
decompiled_smart_contract = latest_decompiled_smart_contract(address.decompiled_smart_contracts)
contract = address.smart_contract || %{}
contract_abi =
if is_nil(address.smart_contract) do
"Contract source code not verified"
else
Jason.encode!(contract.abi)
end
contract_optimization =
case Map.get(contract, :optimization, "") do
true ->
"1"
false ->
"0"
"" ->
""
end
%{
"Address" => to_string(contract.address_hash),
"SourceCode" => contract.contract_source_code,
"ABI" => Jason.encode!(contract.abi),
"ContractName" => contract.name,
"Address" => to_string(address.hash),
"SourceCode" => Map.get(contract, :contract_source_code, ""),
"ABI" => contract_abi,
"ContractName" => Map.get(contract, :name, ""),
"DecompiledSourceCode" => decompiled_source_code(decompiled_smart_contract),
"DecompilerVersion" => decompiler_version(decompiled_smart_contract),
"CompilerVersion" => contract.compiler_version,
"OptimizationUsed" => if(contract.optimization, do: "1", else: "0")
"CompilerVersion" => Map.get(contract, :compiler_version, ""),
"OptimizationUsed" => contract_optimization
}
end
@ -63,10 +83,8 @@ defmodule BlockScoutWeb.API.RPC.ContractView do
%{
"Address" => to_string(hash),
"SourceCode" => "",
"ABI" => "Contract source code not verified",
"ContractName" => "",
"DecompiledSourceCode" => decompiled_source_code(decompiled_smart_contract),
"DecompilerVersion" => decompiler_version(decompiled_smart_contract),
"CompilerVersion" => "",
"OptimizationUsed" => ""
@ -82,10 +100,8 @@ defmodule BlockScoutWeb.API.RPC.ContractView do
%{
"Address" => to_string(hash),
"SourceCode" => contract.contract_source_code,
"ABI" => Jason.encode!(contract.abi),
"ContractName" => contract.name,
"DecompiledSourceCode" => decompiled_source_code(decompiled_smart_contract),
"DecompilerVersion" => decompiler_version(decompiled_smart_contract),
"CompilerVersion" => contract.compiler_version,
"OptimizationUsed" => if(contract.optimization, do: "1", else: "0")

@ -2,8 +2,68 @@ defmodule BlockScoutWeb.LayoutView do
use BlockScoutWeb, :view
alias Plug.Conn
alias Poison.Parser
@issue_url "https://github.com/poanetwork/blockscout/issues/new"
@default_other_networks [
%{
title: "POA Core",
url: "https://blockscout.com/poa/core"
},
%{
title: "POA Sokol",
url: "https://blockscout.com/poa/sokol",
test_net?: true
},
%{
title: "xDai Chain",
url: "https://blockscout.com/poa/dai"
},
%{
title: "Ethereum Mainnet",
url: "https://blockscout.com/eth/mainnet"
},
%{
title: "Kovan Testnet",
url: "https://blockscout.com/eth/kovan",
test_net?: true
},
%{
title: "Ropsten Testnet",
url: "https://blockscout.com/eth/ropsten",
test_net?: true
},
%{
title: "Goerli Testnet",
url: "https://blockscout.com/eth/goerli",
test_net?: true
},
%{
title: "Rinkeby Testnet",
url: "https://blockscout.com/eth/rinkeby",
test_net?: true
},
%{
title: "Ethereum Classic",
url: "https://blockscout.com/etc/mainnet",
other?: true
},
%{
title: "Aerum Mainnet",
url: "https://blockscout.com/aerum/mainnet",
other?: true
},
%{
title: "Callisto Mainnet",
url: "https://blockscout.com/callisto/mainnet",
other?: true
},
%{
title: "RSK Mainnet",
url: "https://blockscout.com/rsk/mainnet",
other?: true
}
]
alias BlockScoutWeb.SocialMedia
@ -95,29 +155,47 @@ defmodule BlockScoutWeb.LayoutView do
def ignore_version?(_), do: false
def other_networks do
get_other_networks =
if Application.get_env(:block_scout_web, :other_networks) do
:block_scout_web
|> Application.get_env(:other_networks, [])
|> Application.get_env(:other_networks)
|> Parser.parse!(%{keys: :atoms!})
else
@default_other_networks
end
get_other_networks
|> Enum.reject(fn %{title: title} ->
title == subnetwork_title()
end)
|> Enum.sort()
end
def main_nets do
Enum.reject(other_networks(), &Map.get(&1, :test_net?))
def main_nets(nets) do
nets
|> Enum.reject(&Map.get(&1, :test_net?))
end
def head_main_nets do
main_nets()
|> Enum.reject(&Map.get(&1, :other?))
def test_nets(nets) do
nets
|> Enum.filter(&Map.get(&1, :test_net?))
end
def dropdown_nets do
other_networks()
|> Enum.reject(&Map.get(&1, :hide_in_dropdown?))
end
def test_nets do
Enum.filter(other_networks(), &Map.get(&1, :test_net?))
def dropdown_head_main_nets do
dropdown_nets()
|> main_nets()
|> Enum.reject(&Map.get(&1, :other?))
end
def other_nets do
Enum.filter(other_networks(), &Map.get(&1, :other?))
def dropdown_other_nets do
dropdown_nets()
|> main_nets()
|> Enum.filter(&Map.get(&1, :other?))
end
def other_explorers do

@ -47,10 +47,8 @@ defmodule BlockScoutWeb.API.RPC.ContractControllerTest do
"Address" => to_string(contract.address_hash),
"CompilerVersion" => contract.compiler_version,
"ContractName" => contract.name,
"DecompiledSourceCode" => "Contract source code not decompiled.",
"DecompilerVersion" => "",
"OptimizationUsed" => if(contract.optimization, do: "1", else: "0"),
"SourceCode" => contract.contract_source_code
"OptimizationUsed" => if(contract.optimization, do: "1", else: "0")
}
]
end
@ -72,10 +70,8 @@ defmodule BlockScoutWeb.API.RPC.ContractControllerTest do
"Address" => to_string(address.hash),
"CompilerVersion" => "",
"ContractName" => "",
"DecompiledSourceCode" => "Contract source code not decompiled.",
"DecompilerVersion" => "",
"OptimizationUsed" => "",
"SourceCode" => ""
"OptimizationUsed" => ""
}
]
end
@ -98,10 +94,8 @@ defmodule BlockScoutWeb.API.RPC.ContractControllerTest do
"Address" => to_string(address.hash),
"CompilerVersion" => "",
"ContractName" => "",
"DecompiledSourceCode" => "Contract source code not decompiled.",
"DecompilerVersion" => "",
"OptimizationUsed" => "",
"SourceCode" => ""
"OptimizationUsed" => ""
}
]
end
@ -123,11 +117,9 @@ defmodule BlockScoutWeb.API.RPC.ContractControllerTest do
"ABI" => Jason.encode!(contract.abi),
"Address" => to_string(contract.address_hash),
"CompilerVersion" => contract.compiler_version,
"DecompiledSourceCode" => "Contract source code not decompiled.",
"DecompilerVersion" => "",
"ContractName" => contract.name,
"OptimizationUsed" => if(contract.optimization, do: "1", else: "0"),
"SourceCode" => contract.contract_source_code
"OptimizationUsed" => if(contract.optimization, do: "1", else: "0")
}
]
end
@ -150,10 +142,8 @@ defmodule BlockScoutWeb.API.RPC.ContractControllerTest do
"Address" => to_string(decompiled_smart_contract.address_hash),
"CompilerVersion" => "",
"ContractName" => "",
"DecompiledSourceCode" => decompiled_smart_contract.decompiled_source_code,
"DecompilerVersion" => "test_decompiler",
"OptimizationUsed" => "",
"SourceCode" => ""
"OptimizationUsed" => ""
}
]
end
@ -176,10 +166,8 @@ defmodule BlockScoutWeb.API.RPC.ContractControllerTest do
"Address" => to_string(smart_contract.address_hash),
"CompilerVersion" => "",
"ContractName" => "",
"DecompiledSourceCode" => smart_contract.decompiled_source_code,
"DecompilerVersion" => "bizbuz",
"OptimizationUsed" => "",
"SourceCode" => ""
"OptimizationUsed" => ""
}
]
end
@ -204,10 +192,8 @@ defmodule BlockScoutWeb.API.RPC.ContractControllerTest do
"Address" => to_string(smart_contract.address_hash),
"CompilerVersion" => "",
"ContractName" => "",
"DecompiledSourceCode" => smart_contract.decompiled_source_code,
"DecompilerVersion" => "bizbuz",
"OptimizationUsed" => "",
"SourceCode" => ""
"OptimizationUsed" => ""
}
]
end
@ -231,10 +217,8 @@ defmodule BlockScoutWeb.API.RPC.ContractControllerTest do
"Address" => to_string(contract_address.hash),
"CompilerVersion" => "",
"ContractName" => "",
"DecompiledSourceCode" => "Contract source code not decompiled.",
"DecompilerVersion" => "",
"OptimizationUsed" => "",
"SourceCode" => ""
"OptimizationUsed" => ""
}
]
end

@ -86,4 +86,123 @@ defmodule BlockScoutWeb.LayoutViewTest do
~s(<a href="https://github.com/poanetwork/blockscout/releases/tag/v1.3.4-beta" class="footer-link" target="_blank">1.3.4</a>)}
end
end
@supported_chains_pattern ~s([ { "title": "RSK Mainnet", "url": "https://blockscout.com/rsk/mainnet", "other?": true }, { "title": "POA Sokol", "url": "https://blockscout.com/poa/sokol", "test_net?": true }, { "title": "POA Core", "url": "https://blockscout.com/poa/core" }, { "title": "LUKSO L14 testnet", "url": "https://blockscout.com/lukso/l14", "test_net?": true, "hide_in_dropdown?": true } ])
describe "other_networks/0" do
test "get networks list based on env variables" do
Application.put_env(:block_scout_web, :other_networks, @supported_chains_pattern)
assert LayoutView.other_networks() == [
%{
title: "POA Core",
url: "https://blockscout.com/poa/core"
},
%{
title: "RSK Mainnet",
url: "https://blockscout.com/rsk/mainnet",
other?: true
},
%{
title: "POA Sokol",
url: "https://blockscout.com/poa/sokol",
test_net?: true
},
%{
title: "LUKSO L14 testnet",
url: "https://blockscout.com/lukso/l14",
test_net?: true,
hide_in_dropdown?: true
}
]
end
end
describe "main_nets/1" do
test "get all main networks list based on env variables" do
Application.put_env(:block_scout_web, :other_networks, @supported_chains_pattern)
assert LayoutView.main_nets(LayoutView.other_networks()) == [
%{
title: "POA Core",
url: "https://blockscout.com/poa/core"
},
%{
title: "RSK Mainnet",
url: "https://blockscout.com/rsk/mainnet",
other?: true
}
]
end
end
describe "test_nets/1" do
test "get all networks list based on env variables" do
Application.put_env(:block_scout_web, :other_networks, @supported_chains_pattern)
assert LayoutView.test_nets(LayoutView.other_networks()) == [
%{
title: "POA Sokol",
url: "https://blockscout.com/poa/sokol",
test_net?: true
},
%{
title: "LUKSO L14 testnet",
url: "https://blockscout.com/lukso/l14",
test_net?: true,
hide_in_dropdown?: true
}
]
end
end
describe "dropdown_nets/0" do
test "get all dropdown networks list based on env variables" do
Application.put_env(:block_scout_web, :other_networks, @supported_chains_pattern)
assert LayoutView.dropdown_nets() == [
%{
title: "POA Core",
url: "https://blockscout.com/poa/core"
},
%{
title: "RSK Mainnet",
url: "https://blockscout.com/rsk/mainnet",
other?: true
},
%{
title: "POA Sokol",
url: "https://blockscout.com/poa/sokol",
test_net?: true
}
]
end
end
describe "dropdown_head_main_nets/0" do
test "get dropdown all main networks except those of 'other' type list based on env variables" do
Application.put_env(:block_scout_web, :other_networks, @supported_chains_pattern)
assert LayoutView.dropdown_head_main_nets() == [
%{
title: "POA Core",
url: "https://blockscout.com/poa/core"
}
]
end
end
describe "dropdown_other_nets/0" do
test "get dropdown networks of 'other' type list based on env variables" do
Application.put_env(:block_scout_web, :other_networks, @supported_chains_pattern)
assert LayoutView.dropdown_other_nets() == [
%{
title: "RSK Mainnet",
url: "https://blockscout.com/rsk/mainnet",
other?: true
}
]
end
end
end

@ -2250,6 +2250,14 @@ defmodule Explorer.Chain do
|> repo.insert(on_conflict: :nothing, conflict_target: [:address_hash, :name])
end
@spec address_hash_to_address_with_source_code(%Explorer.Chain.Hash{}) :: %Explorer.Chain.Address{} | nil
def address_hash_to_address_with_source_code(%Explorer.Chain.Hash{} = address_hash) do
case Repo.get(Address, address_hash) do
nil -> nil
address -> Repo.preload(address, [:smart_contract, :decompiled_smart_contracts])
end
end
@spec address_hash_to_smart_contract(%Explorer.Chain.Hash{}) :: %Explorer.Chain.SmartContract{} | nil
def address_hash_to_smart_contract(%Explorer.Chain.Hash{} = address_hash) do
query =

@ -62,7 +62,7 @@ defmodule Explorer.Chain.Address do
except: [
:__meta__,
:smart_contract,
:decompiled_smart_contract,
:decompiled_smart_contracts,
:token,
:contracts_creation_internal_transaction,
:contracts_creation_transaction,

Loading…
Cancel
Save