Merge pull request #3307 from poanetwork/vb-replace-latest-compiler-version

Replace "latest" compiler version with the actual one
pull/3308/head
Victor Baranov 4 years ago committed by GitHub
commit e3621d3bfe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      .dialyzer-ignore
  2. 1
      CHANGELOG.md
  3. 5
      apps/explorer/lib/explorer/smart_contract/publisher.ex
  4. 2
      apps/explorer/lib/explorer/smart_contract/solc_downloader.ex
  5. 25
      apps/explorer/lib/explorer/smart_contract/solidity/compiler_version.ex
  6. 48
      apps/explorer/lib/explorer/smart_contract/verifier.ex
  7. 47
      apps/explorer/test/explorer/smart_contract/verifier_test.exs

@ -26,3 +26,4 @@ lib/indexer/fetcher/token_total_supply_on_demand.ex:16
lib/explorer/exchange_rates/source.ex:41
lib/explorer/exchange_rates/source/coin_gecko.ex:115
lib/explorer/exchange_rates/source/coin_gecko.ex:136
lib/explorer/smart_contract/verifier.ex:89

@ -11,6 +11,7 @@
- [#3261](https://github.com/poanetwork/blockscout/pull/3261) - Bridged tokens table
### Fixes
- [#3307](https://github.com/poanetwork/blockscout/pull/3307) - Replace "latest" compiler version with the actual one
- [#3303](https://github.com/poanetwork/blockscout/pull/3303) - Address contract twins feature performance
- [#3295](https://github.com/poanetwork/blockscout/pull/3295) - Token instance: check if external_url is not null before trimming
- [#3291](https://github.com/poanetwork/blockscout/pull/3291) - Support unlimited number of external rewards in block

@ -5,6 +5,7 @@ defmodule Explorer.SmartContract.Publisher do
alias Explorer.Chain
alias Explorer.Chain.SmartContract
alias Explorer.SmartContract.Solidity.CompilerVersion
alias Explorer.SmartContract.Verifier
@doc """
@ -76,10 +77,12 @@ defmodule Explorer.SmartContract.Publisher do
prepared_external_libraries = prepare_external_libraies(params["external_libraries"])
compiler_version = CompilerVersion.get_strict_compiler_version(params["compiler_version"])
%{
address_hash: address_hash,
name: params["name"],
compiler_version: params["compiler_version"],
compiler_version: compiler_version,
evm_version: params["evm_version"],
optimization_runs: params["optimization_runs"],
optimization: params["optimization"],

@ -12,7 +12,7 @@ defmodule Explorer.SmartContract.SolcDownloader do
def ensure_exists(version) do
path = file_path(version)
if File.exists?(path) do
if File.exists?(path) && version !== "latest" do
path
else
{:ok, compiler_versions} = CompilerVersion.fetch_versions()

@ -60,4 +60,29 @@ defmodule Explorer.SmartContract.Solidity.CompilerVersion do
"#{solc_bin_api_url}/bin/list.json"
end
def get_strict_compiler_version(compiler_version) do
if compiler_version == "latest" do
{:ok, compiler_versions} = fetch_versions()
if Enum.count(compiler_versions) > 1 do
latest_stable_version =
compiler_versions
|> Enum.drop(1)
|> Enum.reduce_while("", fn version, acc ->
if String.contains?(version, "-nightly") do
{:cont, acc}
else
{:halt, version}
end
end)
latest_stable_version
else
"latest"
end
else
compiler_version
end
end
end

@ -33,14 +33,20 @@ defmodule Explorer.SmartContract.Verifier do
all_versions_extra = all_versions ++ [evm_version]
Enum.reduce(all_versions_extra, false, fn version, acc ->
Enum.reduce_while(all_versions_extra, false, fn version, acc ->
case acc do
{:ok, _} = result ->
result
{:cont, result}
{:error, :compiler_version} ->
{:halt, acc}
{:error, :name} ->
{:halt, acc}
_ ->
cur_params = Map.put(params, "evm_version", version)
verify(address_hash, cur_params)
{:cont, verify(address_hash, cur_params)}
end
end)
end
@ -112,13 +118,13 @@ defmodule Explorer.SmartContract.Verifier do
%{
"metadata_hash" => _metadata_hash,
"bytecode" => blockchain_bytecode_without_whisper,
"compiler_version" => compiler_version
"compiler_version" => compiler_version_from_input
} = extract_bytecode_and_metadata_hash(blockchain_created_tx_input)
empty_constructor_arguments = arguments_data == "" or arguments_data == nil
cond do
generated_compiler_version != compiler_version ->
compiler_version_from_input != generated_compiler_version ->
{:error, :compiler_version}
generated_bytecode != blockchain_bytecode_without_whisper &&
@ -226,7 +232,9 @@ defmodule Explorer.SmartContract.Verifier do
@metadata_hash_prefix_0_5_family_2 <>
<<metadata_hash::binary-size(64)>> <>
@metadata_hash_common_suffix <>
"7826" <> <<compiler_version::binary-size(76)>> <> "0057" <> _constructor_arguments ->
"78" <>
<<_::binary-size(2)>> <>
<<compiler_version::binary-size(76)>> <> "00" <> <<_::binary-size(2)>> <> _constructor_arguments ->
do_extract_bytecode_and_metadata_hash_output(metadata_hash, extracted, compiler_version)
<<_::binary-size(2)>> <>
@ -235,7 +243,9 @@ defmodule Explorer.SmartContract.Verifier do
@metadata_hash_prefix_0_5_family_2 <>
<<metadata_hash::binary-size(64)>> <>
@metadata_hash_common_suffix <>
"7827" <> <<compiler_version::binary-size(78)>> <> "0057" <> _constructor_arguments ->
"78" <>
<<_::binary-size(2)>> <>
<<compiler_version::binary-size(78)>> <> "00" <> <<_::binary-size(2)>> <> _constructor_arguments ->
do_extract_bytecode_and_metadata_hash_output(metadata_hash, extracted, compiler_version)
<<_::binary-size(2)>> <>
@ -244,7 +254,9 @@ defmodule Explorer.SmartContract.Verifier do
@metadata_hash_prefix_0_5_family_2 <>
<<metadata_hash::binary-size(64)>> <>
@metadata_hash_common_suffix <>
"7828" <> <<compiler_version::binary-size(80)>> <> "0058" <> _constructor_arguments ->
"78" <>
<<_::binary-size(2)>> <>
<<compiler_version::binary-size(80)>> <> "00" <> <<_::binary-size(2)>> <> _constructor_arguments ->
do_extract_bytecode_and_metadata_hash_output(metadata_hash, extracted, compiler_version)
<<_::binary-size(2)>> <>
@ -253,7 +265,9 @@ defmodule Explorer.SmartContract.Verifier do
@metadata_hash_prefix_0_5_family_2 <>
<<metadata_hash::binary-size(64)>> <>
@metadata_hash_common_suffix <>
"7829" <> <<compiler_version::binary-size(82)>> <> "0059" <> _constructor_arguments ->
"78" <>
<<_::binary-size(2)>> <>
<<compiler_version::binary-size(82)>> <> "00" <> <<_::binary-size(2)>> <> _constructor_arguments ->
do_extract_bytecode_and_metadata_hash_output(metadata_hash, extracted, compiler_version)
# Solidity >= 0.6.0 https://github.com/ethereum/solidity/blob/develop/Changelog.md#060-2019-12-17
@ -275,25 +289,33 @@ defmodule Explorer.SmartContract.Verifier do
@metadata_hash_prefix_0_6_0 <>
<<metadata_hash::binary-size(68)>> <>
@metadata_hash_common_suffix <>
"7826" <> <<compiler_version::binary-size(76)>> <> "0057" <> _constructor_arguments ->
"78" <>
<<_::binary-size(2)>> <>
<<compiler_version::binary-size(76)>> <> "00" <> <<_::binary-size(2)>> <> _constructor_arguments ->
do_extract_bytecode_and_metadata_hash_output(metadata_hash, extracted, compiler_version)
@metadata_hash_prefix_0_6_0 <>
<<metadata_hash::binary-size(68)>> <>
@metadata_hash_common_suffix <>
"7827" <> <<compiler_version::binary-size(78)>> <> "0057" <> _constructor_arguments ->
"78" <>
<<_::binary-size(2)>> <>
<<compiler_version::binary-size(78)>> <> "00" <> <<_::binary-size(2)>> <> _constructor_arguments ->
do_extract_bytecode_and_metadata_hash_output(metadata_hash, extracted, compiler_version)
@metadata_hash_prefix_0_6_0 <>
<<metadata_hash::binary-size(68)>> <>
@metadata_hash_common_suffix <>
"7828" <> <<compiler_version::binary-size(80)>> <> "0058" <> _constructor_arguments ->
"78" <>
<<_::binary-size(2)>> <>
<<compiler_version::binary-size(80)>> <> "00" <> <<_::binary-size(2)>> <> _constructor_arguments ->
do_extract_bytecode_and_metadata_hash_output(metadata_hash, extracted, compiler_version)
@metadata_hash_prefix_0_6_0 <>
<<metadata_hash::binary-size(68)>> <>
@metadata_hash_common_suffix <>
"7829" <> <<compiler_version::binary-size(82)>> <> "0059" <> _constructor_arguments ->
"78" <>
<<_::binary-size(2)>> <>
<<compiler_version::binary-size(82)>> <> "00" <> <<_::binary-size(2)>> <> _constructor_arguments ->
do_extract_bytecode_and_metadata_hash_output(metadata_hash, extracted, compiler_version)
<<next::binary-size(2)>> <> rest ->

@ -757,33 +757,32 @@ defmodule Explorer.SmartContract.VerifierTest do
assert abi != nil
end
# flaky test
# test "verification is failed if wrong nightly version of compiler ~0.5.11" do
# bytecode_0_5_11_nightly_2019_6_25_commit_1cc84753 =
# "0x608060405234801561001057600080fd5b5060405161026b38038061026b8339818101604052602081101561003357600080fd5b81019080805190602001909291905050508060008190555033600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550506101cf8061009c6000396000f3fe608060405234801561001057600080fd5b506004361061005e576000357c010000000000000000000000000000000000000000000000000000000090048063256fec88146100635780633fa4f245146100ad578063812600df146100cb575b600080fd5b61006b6100f9565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6100b561011f565b6040518082815260200191505060405180910390f35b6100f7600480360360208110156100e157600080fd5b8101908080359060200190929190505050610125565b005b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60005481565b806000540160008190555033600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505056fea265627a7a72305820f7420b8c3b16d83ce728d8c279f0f887c4dcd7bfcd38c484acc9cdb82fde785764736f6c637828302e352e31312d6e696768746c792e323031392e362e32352b636f6d6d69742e31636338343735330058"
test "verification is failed if wrong nightly version of compiler ~0.5.11" do
bytecode_0_5_11_nightly_2019_6_25_commit_1cc84753 =
"0x608060405234801561001057600080fd5b5060405161026b38038061026b8339818101604052602081101561003357600080fd5b81019080805190602001909291905050508060008190555033600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550506101cf8061009c6000396000f3fe608060405234801561001057600080fd5b506004361061005e576000357c010000000000000000000000000000000000000000000000000000000090048063256fec88146100635780633fa4f245146100ad578063812600df146100cb575b600080fd5b61006b6100f9565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6100b561011f565b6040518082815260200191505060405180910390f35b6100f7600480360360208110156100e157600080fd5b8101908080359060200190929190505050610125565b005b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60005481565b806000540160008190555033600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505056fea265627a7a72305820f7420b8c3b16d83ce728d8c279f0f887c4dcd7bfcd38c484acc9cdb82fde785764736f6c637828302e352e31312d6e696768746c792e323031392e362e32352b636f6d6d69742e31636338343735330058"
# constructor_arguments = "000000000000000000000000000000000000000000000000000000000000000a"
# contract_address = insert(:contract_address, contract_code: bytecode_0_5_11_nightly_2019_6_25_commit_1cc84753)
# bytecode_construtor_arguments = "#{bytecode_0_5_11_nightly_2019_6_25_commit_1cc84753}#{constructor_arguments}"
constructor_arguments = "000000000000000000000000000000000000000000000000000000000000000a"
contract_address = insert(:contract_address, contract_code: bytecode_0_5_11_nightly_2019_6_25_commit_1cc84753)
bytecode_construtor_arguments = "#{bytecode_0_5_11_nightly_2019_6_25_commit_1cc84753}#{constructor_arguments}"
# :transaction
# |> insert(
# created_contract_address_hash: contract_address.hash,
# input: bytecode_construtor_arguments
# )
# |> with_block()
:transaction
|> insert(
created_contract_address_hash: contract_address.hash,
input: bytecode_construtor_arguments
)
|> with_block()
# params = %{
# "contract_source_code" => @code_0_5,
# "compiler_version" => "v0.5.11-nightly.2019.8.10+commit.f5f2bbb2",
# "evm_version" => "homestead",
# "name" => "Incrementer",
# "optimization" => false,
# "constructor_arguments" => constructor_arguments
# }
params = %{
"contract_source_code" => @code_0_5,
"compiler_version" => "v0.5.11-nightly.2019.8.10+commit.f5f2bbb2",
"evm_version" => "homestead",
"name" => "Incrementer",
"optimization" => false,
"constructor_arguments" => constructor_arguments
}
# response = Verifier.evaluate_authenticity(contract_address.hash, params)
# assert {:error, :compiler_version} = response
# end
response = Verifier.evaluate_authenticity(contract_address.hash, params)
assert {:error, :compiler_version} = response
end
end
end

Loading…
Cancel
Save