Merge pull request #1662 from poanetwork/ab-specify-number-of-optimization-runs

allow specifying number of optimization runs
pull/1658/head
Ayrat Badykov 6 years ago committed by GitHub
commit e7187d6051
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 5
      CHANGELOG.md
  2. 15
      apps/block_scout_web/lib/block_scout_web/controllers/address_contract_verification_controller.ex
  3. 5
      apps/block_scout_web/lib/block_scout_web/templates/address_contract_verification/new.html.eex
  4. 51
      apps/block_scout_web/priv/gettext/default.pot
  5. 53
      apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po
  6. 27
      apps/explorer/lib/explorer/smart_contract/solidity/code_compiler.ex
  7. 23
      apps/explorer/lib/explorer/smart_contract/verifier.ex
  8. 9
      apps/explorer/priv/compile_solc.js
  9. 49
      apps/explorer/test/explorer/smart_contract/solidity/code_compiler_test.exs

@ -2,8 +2,9 @@
### Features
- [1654](https://github.com/poanetwork/blockscout/pull/1654) - add decompiled code tab
- [1661](https://github.com/poanetwork/blockscout/pull/1661) - try to compile smart contract with the latest evm version
- [#1662](https://github.com/poanetwork/blockscout/pull/1662) - allow specifying number of optimization runs
- [#1654](https://github.com/poanetwork/blockscout/pull/1654) - add decompiled code tab
- [#1661](https://github.com/poanetwork/blockscout/pull/1661) - try to compile smart contract with the latest evm version
### Fixes

@ -26,10 +26,14 @@ defmodule BlockScoutWeb.AddressContractVerificationController do
"address_id" => address_hash_string,
"smart_contract" => smart_contract,
"external_libraries" => external_libraries,
"evm_version" => evm_version
"evm_version" => evm_version,
"optimization" => optimization
}
) do
smart_sontact_with_evm_version = Map.put(smart_contract, "evm_version", evm_version["evm_version"])
smart_sontact_with_evm_version =
smart_contract
|> Map.put("evm_version", evm_version["evm_version"])
|> Map.put("optimization_runs", parse_optimization_runs(optimization))
case Publisher.publish(address_hash_string, smart_sontact_with_evm_version, external_libraries) do
{:ok, _smart_contract} ->
@ -45,4 +49,11 @@ defmodule BlockScoutWeb.AddressContractVerificationController do
)
end
end
def parse_optimization_runs(%{"runs" => runs}) do
case Integer.parse(runs) do
{integer, ""} -> integer
_ -> 200
end
end
end

@ -48,6 +48,11 @@
<%= error_tag f, :optimization, id: "optimization-help-block", class: "text-danger" %>
</div>
<div class="form-group">
<%= label f, :name, gettext("Optimization runs") %>
<%= text_input :optimization, :runs, value: 200, class: "form-control", "aria-describedby": "optimization-runs-help-block", "data-test": "optimization-runs" %>
</div>
<div class="form-group mb-4">
<%= label f, :contract_source_code, gettext("Enter the Solidity Contract Code below") %>
<%= textarea f, :contract_source_code, class: "form-control monospace", rows: 3, "aria-describedby": "contract-source-code-help-block" %>

@ -197,7 +197,7 @@ msgid "Blocks Validated"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:130
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:135
#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:24
msgid "Cancel"
msgstr ""
@ -367,7 +367,7 @@ msgid "ETH"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:52
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:57
msgid "Enter the Solidity Contract Code below"
msgstr ""
@ -713,7 +713,7 @@ msgid "Request URL"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:128
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:133
msgid "Reset"
msgstr ""
@ -1024,7 +1024,7 @@ msgid "Verify & Publish"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:127
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:132
msgid "Verify & publish"
msgstr ""
@ -1165,7 +1165,7 @@ msgid "Loading..."
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:125
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:130
msgid "Loading...."
msgstr ""
@ -1582,57 +1582,57 @@ msgid "Genesis Block"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:71
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:76
msgid "1 Library Address"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:66
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:71
msgid "1 Library Name"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:81
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:86
msgid "2 Library Address"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:76
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:81
msgid "2 Library Name"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:91
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:96
msgid "3 Library Address"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:86
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:91
msgid "3 Library Name"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:101
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:106
msgid "4 Library Address"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:96
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:101
msgid "4 Library Name"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:111
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:116
msgid "5 Library Address"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:106
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:111
msgid "5 Library Name"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:63
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:68
msgid "Contract Libraries"
msgstr ""
@ -1698,16 +1698,10 @@ msgid "EVM Version"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:58
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:63
msgid "Enter constructor arguments if the contract had any"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_tabs.html.eex:67
#: lib/block_scout_web/templates/address/_tabs.html.eex:133
msgid "Decompiled code"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_decompiled_contract/index.html.eex:20
msgid "Copy Decompiled Contract Code"
@ -1718,6 +1712,12 @@ msgstr ""
msgid "Decompiled Code"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_tabs.html.eex:67
#: lib/block_scout_web/templates/address/_tabs.html.eex:133
msgid "Decompiled code"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_decompiled_contract/index.html.eex:18
msgid "Decompiled contract code"
@ -1727,3 +1727,8 @@ msgstr ""
#: lib/block_scout_web/templates/address_decompiled_contract/index.html.eex:11
msgid "Decompiler version"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:52
msgid "Optimization runs"
msgstr ""

@ -197,7 +197,7 @@ msgid "Blocks Validated"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:130
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:135
#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:24
msgid "Cancel"
msgstr ""
@ -367,7 +367,7 @@ msgid "ETH"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:52
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:57
msgid "Enter the Solidity Contract Code below"
msgstr ""
@ -713,7 +713,7 @@ msgid "Request URL"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:128
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:133
msgid "Reset"
msgstr ""
@ -1024,7 +1024,7 @@ msgid "Verify & Publish"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:127
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:132
msgid "Verify & publish"
msgstr ""
@ -1165,7 +1165,7 @@ msgid "Loading..."
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:125
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:130
msgid "Loading...."
msgstr ""
@ -1582,57 +1582,57 @@ msgid "Genesis Block"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:71
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:76
msgid "1 Library Address"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:66
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:71
msgid "1 Library Name"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:81
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:86
msgid "2 Library Address"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:76
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:81
msgid "2 Library Name"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:91
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:96
msgid "3 Library Address"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:86
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:91
msgid "3 Library Name"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:101
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:106
msgid "4 Library Address"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:96
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:101
msgid "4 Library Name"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:111
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:116
msgid "5 Library Address"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:106
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:111
msgid "5 Library Name"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:63
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:68
msgid "Contract Libraries"
msgstr ""
@ -1698,16 +1698,10 @@ msgid "EVM Version"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:58
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:63
msgid "Enter constructor arguments if the contract had any"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_tabs.html.eex:67
#: lib/block_scout_web/templates/address/_tabs.html.eex:133
msgid "Decompiled code"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_decompiled_contract/index.html.eex:20
msgid "Copy Decompiled Contract Code"
@ -1718,12 +1712,23 @@ msgstr ""
msgid "Decompiled Code"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_tabs.html.eex:67
#: lib/block_scout_web/templates/address/_tabs.html.eex:133
msgid "Decompiled code"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_decompiled_contract/index.html.eex:18
msgid "Decompiled contract code"
msgstr ""
#, elixir-format
#, elixir-format, fuzzy
#: lib/block_scout_web/templates/address_decompiled_contract/index.html.eex:11
msgid "Decompiler version"
msgstr ""
#, elixir-format, fuzzy
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:52
msgid "Optimization runs"
msgstr ""

@ -13,10 +13,10 @@ defmodule Explorer.SmartContract.Solidity.CodeCompiler do
## Examples
iex(1)> Explorer.SmartContract.Solidity.CodeCompiler.run(
...> "SimpleStorage",
...> "v0.4.24+commit.e67f0147",
...> \"""
iex(1)> Explorer.SmartContract.Solidity.CodeCompiler.run([
...> name: "SimpleStorage",
...> compiler_version: "v0.4.24+commit.e67f0147",
...> code: \"""
...> pragma solidity ^0.4.24;
...>
...> contract SimpleStorage {
@ -31,8 +31,8 @@ defmodule Explorer.SmartContract.Solidity.CodeCompiler do
...> }
...> }
...> \""",
...> false
...> )
...> optimize: false, evm_version: "byzantium"
...> ])
{
:ok,
%{
@ -61,10 +61,18 @@ defmodule Explorer.SmartContract.Solidity.CodeCompiler do
}
}
"""
def run(name, compiler_version, code, optimize, evm_version \\ "byzantium", external_libs \\ %{}) do
def run(params) do
name = Keyword.fetch!(params, :name)
compiler_version = Keyword.fetch!(params, :compiler_version)
code = Keyword.fetch!(params, :code)
optimize = Keyword.fetch!(params, :optimize)
optimization_runs = params |> Keyword.get(:optimization_runs, 200) |> Integer.to_string()
evm_version = Keyword.get(params, :evm_version, List.last(@allowed_evm_versions))
external_libs = Keyword.get(params, :external_libs, %{})
external_libs_string = Jason.encode!(external_libs)
evm_version =
checked_evm_version =
if evm_version in @allowed_evm_versions do
evm_version
else
@ -79,9 +87,10 @@ defmodule Explorer.SmartContract.Solidity.CodeCompiler do
code,
compiler_version,
optimize_value(optimize),
optimization_runs,
@new_contract_name,
external_libs_string,
evm_version
checked_evm_version
]
)

@ -24,9 +24,18 @@ defmodule Explorer.SmartContract.Verifier do
external_libraries = Map.get(params, "external_libraries", %{})
constructor_arguments = Map.get(params, "constructor_arguments", "")
evm_version = Map.get(params, "evm_version", "byzantium")
optimization_runs = Map.get(params, "optimization_runs", 200)
solc_output =
CodeCompiler.run(name, compiler_version, contract_source_code, optimization, evm_version, external_libraries)
CodeCompiler.run(
name: name,
compiler_version: compiler_version,
code: contract_source_code,
optimize: optimization,
optimization_runs: optimization_runs,
evm_version: evm_version,
external_libs: external_libraries
)
case compare_bytecodes(solc_output, address_hash, constructor_arguments) do
{:error, :generated_bytecode} ->
@ -34,12 +43,12 @@ defmodule Explorer.SmartContract.Verifier do
second_solc_output =
CodeCompiler.run(
name,
compiler_version,
contract_source_code,
optimization,
next_evm_version,
external_libraries
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)

@ -5,9 +5,10 @@ const solc = require('solc');
var sourceCode = process.argv[2];
var version = process.argv[3];
var optimize = process.argv[4];
var newContractName = process.argv[5];
var externalLibraries = JSON.parse(process.argv[6])
var evmVersion = process.argv[7]
var optimizationRuns = parseInt(process.argv[5], 10);
var newContractName = process.argv[6];
var externalLibraries = JSON.parse(process.argv[7])
var evmVersion = process.argv[8];
var compiled_code = solc.loadRemoteVersion(version, function (err, solcSnapshot) {
if (err) {
@ -24,7 +25,7 @@ var compiled_code = solc.loadRemoteVersion(version, function (err, solcSnapshot)
evmVersion: evmVersion,
optimizer: {
enabled: optimize == '1',
runs: 200
runs: optimizationRuns
},
libraries: {
[newContractName]: externalLibraries

@ -18,10 +18,11 @@ defmodule Explorer.SmartContract.Solidity.CodeCompilerTest do
test "compiles the latest solidity version", %{contract_code_info: contract_code_info} do
response =
CodeCompiler.run(
contract_code_info.name,
contract_code_info.version,
contract_code_info.source_code,
contract_code_info.optimized
name: contract_code_info.name,
compiler_version: contract_code_info.version,
code: contract_code_info.source_code,
optimize: contract_code_info.optimized,
evm_version: "byzantium"
)
assert {:ok,
@ -37,10 +38,11 @@ defmodule Explorer.SmartContract.Solidity.CodeCompilerTest do
response =
CodeCompiler.run(
contract_code_info.name,
contract_code_info.version,
contract_code_info.source_code,
optimize
name: contract_code_info.name,
compiler_version: contract_code_info.version,
code: contract_code_info.source_code,
optimize: optimize,
evm_version: "byzantium"
)
assert {:ok,
@ -61,12 +63,12 @@ defmodule Explorer.SmartContract.Solidity.CodeCompilerTest do
{:ok, result} =
CodeCompiler.run(
name,
compiler_version,
contract,
optimize,
"byzantium",
external_libraries
name: name,
compiler_version: compiler_version,
code: contract,
optimize: optimize,
evm_version: "byzantium",
external_libs: external_libraries
)
clean_result = remove_init_data_and_whisper_data(result["bytecode"])
@ -109,7 +111,14 @@ defmodule Explorer.SmartContract.Solidity.CodeCompilerTest do
evm_version = "constantinople"
response = CodeCompiler.run(name, version, code, optimize, evm_version)
response =
CodeCompiler.run(
name: name,
compiler_version: version,
code: code,
optimize: optimize,
evm_version: evm_version
)
assert {:ok,
%{
@ -139,7 +148,7 @@ defmodule Explorer.SmartContract.Solidity.CodeCompilerTest do
version = "v0.1.3-nightly.2015.9.25+commit.4457170"
response = CodeCompiler.run(name, version, code, optimize)
response = CodeCompiler.run(name: name, compiler_version: version, code: code, optimize: optimize)
assert {:ok,
%{
@ -156,10 +165,10 @@ defmodule Explorer.SmartContract.Solidity.CodeCompilerTest do
response =
CodeCompiler.run(
contract_code_info.name,
contract_code_info.version,
wrong_code,
contract_code_info.optimized
name: contract_code_info.name,
compiler_version: contract_code_info.version,
code: wrong_code,
optimize: contract_code_info.optimized
)
assert {:error, :compilation} = response

Loading…
Cancel
Save