diff --git a/apps/explorer/lib/explorer/smart_contract/verifier.ex b/apps/explorer/lib/explorer/smart_contract/verifier.ex index 4b521fba35..662bde1515 100644 --- a/apps/explorer/lib/explorer/smart_contract/verifier.ex +++ b/apps/explorer/lib/explorer/smart_contract/verifier.ex @@ -17,13 +17,28 @@ defmodule Explorer.SmartContract.Verifier do do: {:error, :contract_source_code} def evaluate_authenticity(address_hash, params) do + evm_version = Map.get(params, "evm_version", "petersburg") + + Enum.reduce([evm_version | previous_evm_versions(evm_version)], false, fn version, acc -> + case acc do + {:ok, _} = result -> + result + + _ -> + cur_params = Map.put(params, "evm_version", version) + verify(address_hash, cur_params) + end + end) + end + + defp verify(address_hash, params) do name = Map.fetch!(params, "name") contract_source_code = Map.fetch!(params, "contract_source_code") optimization = Map.fetch!(params, "optimization") compiler_version = Map.fetch!(params, "compiler_version") external_libraries = Map.get(params, "external_libraries", %{}) constructor_arguments = Map.get(params, "constructor_arguments", "") - evm_version = Map.get(params, "evm_version", "byzantium") + evm_version = Map.get(params, "evm_version") optimization_runs = Map.get(params, "optimization_runs", 200) solc_output = @@ -37,25 +52,7 @@ defmodule Explorer.SmartContract.Verifier do external_libs: external_libraries ) - case compare_bytecodes(solc_output, address_hash, constructor_arguments) do - {:error, :generated_bytecode} -> - next_evm_version = next_evm_version(evm_version) - - second_solc_output = - CodeCompiler.run( - name: name, - compiler_version: compiler_version, - code: contract_source_code, - optimize: optimization, - evm_version: next_evm_version, - external_libs: external_libraries - ) - - compare_bytecodes(second_solc_output, address_hash, constructor_arguments) - - result -> - result - end + compare_bytecodes(solc_output, address_hash, constructor_arguments) end defp compare_bytecodes({:error, :name}, _, _), do: {:error, :name} @@ -99,16 +96,21 @@ defmodule Explorer.SmartContract.Verifier do bytecode end - def next_evm_version(current_evm_version) do - [prev_version, last_version] = - CodeCompiler.allowed_evm_versions() - |> Enum.reverse() - |> Enum.take(2) + def previous_evm_versions(current_evm_version) do + index = Enum.find_index(CodeCompiler.allowed_evm_versions(), fn el -> el == current_evm_version end) + + cond do + index == 0 -> + [] - if current_evm_version != last_version do - last_version - else - prev_version + index == 1 -> + [List.first(CodeCompiler.allowed_evm_versions())] + + true -> + [ + Enum.at(CodeCompiler.allowed_evm_versions(), index - 1), + Enum.at(CodeCompiler.allowed_evm_versions(), index - 2) + ] end end