Merge pull request #2235 from poanetwork/ab-add-new-fields-for-contract-verification

save and show additional validation fields to smart contract
pull/2275/head
Victor Baranov 5 years ago committed by GitHub
commit fe4761477b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      CHANGELOG.md
  2. 11
      apps/block_scout_web/lib/block_scout_web/controllers/address_contract_verification_controller.ex
  3. 31
      apps/block_scout_web/lib/block_scout_web/templates/address_contract/index.html.eex
  4. 4
      apps/block_scout_web/lib/block_scout_web/templates/address_contract_verification/new.html.eex
  5. 66
      apps/block_scout_web/priv/gettext/default.pot
  6. 68
      apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po
  7. 22
      apps/explorer/lib/explorer/chain/smart_contract.ex
  8. 3
      apps/explorer/lib/explorer/smart_contract/publisher.ex
  9. 12
      apps/explorer/lib/explorer/smart_contract/solidity/code_compiler.ex
  10. 11
      apps/explorer/priv/repo/migrations/20190625085852_add_additional_contract_fields.exs

@ -6,6 +6,7 @@
- [#2151](https://github.com/poanetwork/blockscout/pull/2151) - hide dropdown menu then other networks list is empty
- [#2191](https://github.com/poanetwork/blockscout/pull/2191) - allow to configure token metadata update interval
- [#2146](https://github.com/poanetwork/blockscout/pull/2146) - feat: add eth_getLogs rpc endpoint
- [#2235](https://github.com/poanetwork/blockscout/pull/2235) - save and show additional validation fields to smart contract
- [#2190](https://github.com/poanetwork/blockscout/pull/2190) - show all token transfers
- [#2193](https://github.com/poanetwork/blockscout/pull/2193) - feat: add BLOCKSCOUT_HOST, and use it in API docs
- [#2266](https://github.com/poanetwork/blockscout/pull/2266) - allow excluding uncles from average block time calculation

@ -25,17 +25,10 @@ defmodule BlockScoutWeb.AddressContractVerificationController do
%{
"address_id" => address_hash_string,
"smart_contract" => smart_contract,
"external_libraries" => external_libraries,
"evm_version" => evm_version,
"optimization" => optimization
"external_libraries" => external_libraries
}
) do
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
case Publisher.publish(address_hash_string, smart_contract, external_libraries) do
{:ok, _smart_contract} ->
redirect(conn, to: address_contract_path(conn, :index, address_hash_string))

@ -30,10 +30,39 @@
<dt class="col-sm-4 col-md-2 text-muted"><%= gettext "Compiler version" %></dt>
<dd class="col-sm-8 col-md-10"><%= @address.smart_contract.compiler_version %></dd>
</dl>
<%= if @address.smart_contract.evm_version do %>
<dl class="row">
<dt class="col-sm-4 col-md-2 text-muted"><%= gettext "EVM Version" %></dt>
<dd class="col-sm-8 col-md-10"><%= @address.smart_contract.evm_version %></dd>
</dl>
<% end %>
<dl class="row">
<dt class="col-sm-4 col-md-2 text-muted"><%= gettext "Optimization enabled" %></dt>
<dd class="col-sm-8 col-md-10"><%= format_optimization_text(@address.smart_contract.optimization) %></dd>
</dl>
<%= if @address.smart_contract.optimization && @address.smart_contract.optimization_runs do %>
<dl class="row">
<dt class="col-sm-4 col-md-2 text-muted"><%= gettext "Optimization runs" %></dt>
<dd class="col-sm-8 col-md-10"><%= @address.smart_contract.optimization_runs %></dd>
</dl>
<% end %>
<%= if @address.smart_contract.constructor_arguments do %>
<dl class="row">
<dt class="col-sm-4 col-md-2 text-muted"><%= gettext "Constructor arguments" %></dt>
<dd class="col-sm-8 col-md-10"><%= @address.smart_contract.constructor_arguments %></dd>
</dl>
<% end %>
<%= if @address.smart_contract.external_libraries do %>
<section>
<div class="d-flex justify-content-between align-items-baseline">
<h3><%= gettext "External libraries" %></h3>
</div>
<div class="tile tile-muted mb-4">
<pre class="pre-wrap pre-scrollable"><code class="nohighlight"><%= format_smart_contract_abi(@address.smart_contract.abi) %></code>
</pre>
</div>
</section>
<% end %>
</div>
<hr/>
<section>
@ -64,7 +93,7 @@
<% end %>
<section>
<%= case contract_creation_code do %>
<% {:selfdestructed, transaction_init} -> %>
<% {:selfdestructed, transaction_init} -> %>
<div class="d-flex justify-content-between align-items-baseline">
<h3><%= gettext "Contract Creation Code" %></h3>
<button type="button" class="button button-secondary button-sm" id="button" data-clipboard-text="<%= transaction_init %>" aria-label="copy contract creation code">

@ -44,7 +44,7 @@
<div class="smart-contract-form-group-inner-wrapper">
<%= label :evm_version, :evm_version, gettext("EVM Version") %>
<div class="center-column">
<%= select :evm_version, :evm_version, @evm_versions, class: "form-control border-rounded", selected: "petersburg", "aria-describedby": "evm-version-help-block" %>
<%= select f, :evm_version, @evm_versions, class: "form-control border-rounded", selected: "petersburg", "aria-describedby": "evm-version-help-block" %>
</div>
<div class="smart-contract-form-group-tooltip">The EVM version the contract is written for. If the bytecode does not match the version, we try to verify using the latest EVM version. <a href="https://forum.poa.network/t/smart-contract-verification-evm-version-details/2318" target="_blank">EVM version details</a>.</div>
</div>
@ -76,7 +76,7 @@
<div class="smart-contract-form-group-inner-wrapper">
<%= label f, :name, gettext("Optimization runs") %>
<div class="center-column">
<%= text_input :optimization, :runs, value: 200, class: "form-control border-rounded", "aria-describedby": "optimization-runs-help-block", "data-test": "optimization-runs" %>
<%= text_input f, :optimization_runs, value: 200, class: "form-control border-rounded", "aria-describedby": "optimization-runs-help-block", "data-test": "optimization-runs" %>
</div>
<div class="smart-contract-form-group-tooltip"></div>
</div>

@ -258,7 +258,7 @@ msgid "Connection Lost, click to load newer validations"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract/index.html.eex:53
#: lib/block_scout_web/templates/address_contract/index.html.eex:82
msgid "Contract ABI"
msgstr ""
@ -296,7 +296,7 @@ msgid "Contract name:"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract/index.html.eex:41
#: lib/block_scout_web/templates/address_contract/index.html.eex:70
msgid "Contract source code"
msgstr ""
@ -577,7 +577,7 @@ msgid "OUT"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract/index.html.eex:34
#: lib/block_scout_web/templates/address_contract/index.html.eex:40
msgid "Optimization enabled"
msgstr ""
@ -1405,17 +1405,17 @@ msgid "Support"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract/index.html.eex:55
#: lib/block_scout_web/templates/address_contract/index.html.eex:84
msgid "Copy ABI"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract/index.html.eex:71
#: lib/block_scout_web/templates/address_contract/index.html.eex:100
msgid "Copy Contract Creation Code"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract/index.html.eex:43
#: lib/block_scout_web/templates/address_contract/index.html.eex:72
msgid "Copy Source Code"
msgstr ""
@ -1487,6 +1487,7 @@ msgid "Search by address, token symbol name, transaction hash, or block number"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract/index.html.eex:35
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:45
msgid "EVM Version"
msgstr ""
@ -1517,6 +1518,7 @@ msgid "Decompiler version"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract/index.html.eex:45
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:77
msgid "Optimization runs"
msgstr ""
@ -1583,27 +1585,27 @@ msgid "Block Details"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract/index.html.eex:83
#: lib/block_scout_web/templates/address_contract/index.html.eex:112
msgid "Contract Byte Code"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract/index.html.eex:69
#: lib/block_scout_web/templates/address_contract/index.html.eex:98
msgid "Contract Creation Code"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract/index.html.eex:75
#: lib/block_scout_web/templates/address_contract/index.html.eex:104
msgid "Contracts that self destruct in their constructors have no contract code published and cannot be verified."
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract/index.html.eex:85
#: lib/block_scout_web/templates/address_contract/index.html.eex:114
msgid "Copy Contract Byte Code"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract/index.html.eex:76
#: lib/block_scout_web/templates/address_contract/index.html.eex:105
msgid "Displaying the init data provided of the creating transaction."
msgstr ""
@ -1740,11 +1742,37 @@ msgstr ""
msgid "here."
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_token/index.html.eex:26
#: lib/block_scout_web/templates/address_transaction/index.html.eex:72
msgid "CSV"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/layout/_network_selector.html.eex:11
msgid "Change Network"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract/index.html.eex:51
msgid "Constructor arguments"
msgstr ""
#, elixir-format
#: lib/block_scout_web/views/transaction_view.ex:44
msgid "ERC-20 "
msgstr ""
#, elixir-format
#: lib/block_scout_web/views/transaction_view.ex:45
msgid "ERC-721 "
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract/index.html.eex:58
msgid "External libraries"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/layout/_network_selector.html.eex:24
msgid "Favorites"
@ -1769,19 +1797,3 @@ msgstr ""
#: lib/block_scout_web/templates/layout/_network_selector.html.eex:23
msgid "Testnet"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_token/index.html.eex:26
#: lib/block_scout_web/templates/address_transaction/index.html.eex:72
msgid "CSV"
msgstr ""
#, elixir-format
#: lib/block_scout_web/views/transaction_view.ex:44
msgid "ERC-20 "
msgstr ""
#, elixir-format
#: lib/block_scout_web/views/transaction_view.ex:45
msgid "ERC-721 "
msgstr ""

@ -258,7 +258,7 @@ msgid "Connection Lost, click to load newer validations"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract/index.html.eex:53
#: lib/block_scout_web/templates/address_contract/index.html.eex:82
msgid "Contract ABI"
msgstr ""
@ -296,7 +296,7 @@ msgid "Contract name:"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract/index.html.eex:41
#: lib/block_scout_web/templates/address_contract/index.html.eex:70
msgid "Contract source code"
msgstr ""
@ -577,7 +577,7 @@ msgid "OUT"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract/index.html.eex:34
#: lib/block_scout_web/templates/address_contract/index.html.eex:40
msgid "Optimization enabled"
msgstr ""
@ -1405,17 +1405,17 @@ msgid "Support"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract/index.html.eex:55
#: lib/block_scout_web/templates/address_contract/index.html.eex:84
msgid "Copy ABI"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract/index.html.eex:71
#: lib/block_scout_web/templates/address_contract/index.html.eex:100
msgid "Copy Contract Creation Code"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract/index.html.eex:43
#: lib/block_scout_web/templates/address_contract/index.html.eex:72
msgid "Copy Source Code"
msgstr ""
@ -1487,6 +1487,7 @@ msgid "Search by address, token symbol name, transaction hash, or block number"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract/index.html.eex:35
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:45
msgid "EVM Version"
msgstr ""
@ -1517,6 +1518,7 @@ msgid "Decompiler version"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract/index.html.eex:45
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:77
msgid "Optimization runs"
msgstr ""
@ -1583,27 +1585,27 @@ msgid "Block Details"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract/index.html.eex:83
#: lib/block_scout_web/templates/address_contract/index.html.eex:112
msgid "Contract Byte Code"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract/index.html.eex:69
#: lib/block_scout_web/templates/address_contract/index.html.eex:98
msgid "Contract Creation Code"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract/index.html.eex:75
#: lib/block_scout_web/templates/address_contract/index.html.eex:104
msgid "Contracts that self destruct in their constructors have no contract code published and cannot be verified."
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract/index.html.eex:85
#: lib/block_scout_web/templates/address_contract/index.html.eex:114
msgid "Copy Contract Byte Code"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract/index.html.eex:76
#: lib/block_scout_web/templates/address_contract/index.html.eex:105
msgid "Displaying the init data provided of the creating transaction."
msgstr ""
@ -1740,48 +1742,58 @@ msgstr ""
msgid "here."
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_token/index.html.eex:26
#: lib/block_scout_web/templates/address_transaction/index.html.eex:72
msgid "CSV"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/layout/_network_selector.html.eex:11
msgid "Change Network"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/layout/_network_selector.html.eex:24
msgid "Favorites"
#: lib/block_scout_web/templates/address_contract/index.html.eex:51
msgid "Constructor arguments"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/layout/_network_selector.html.eex:12
msgid "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore."
#: lib/block_scout_web/views/transaction_view.ex:44
msgid "ERC-20 "
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/layout/_network_selector.html.eex:22
msgid "Mainnet"
#: lib/block_scout_web/views/transaction_view.ex:45
msgid "ERC-721 "
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/layout/_network_selector.html.eex:18
msgid "Search network"
#: lib/block_scout_web/templates/address_contract/index.html.eex:58
msgid "External libraries"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/layout/_network_selector.html.eex:23
msgid "Testnet"
#: lib/block_scout_web/templates/layout/_network_selector.html.eex:24
msgid "Favorites"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_token/index.html.eex:26
#: lib/block_scout_web/templates/address_transaction/index.html.eex:72
msgid "CSV"
#: lib/block_scout_web/templates/layout/_network_selector.html.eex:12
msgid "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore."
msgstr ""
#, elixir-format
#: lib/block_scout_web/views/transaction_view.ex:44
msgid "ERC-20 "
#: lib/block_scout_web/templates/layout/_network_selector.html.eex:22
msgid "Mainnet"
msgstr ""
#, elixir-format, fuzzy
#: lib/block_scout_web/templates/layout/_network_selector.html.eex:18
msgid "Search network"
msgstr ""
#, elixir-format
#: lib/block_scout_web/views/transaction_view.ex:45
msgid "ERC-721 "
#: lib/block_scout_web/templates/layout/_network_selector.html.eex:23
msgid "Testnet"
msgstr ""

@ -198,6 +198,9 @@ defmodule Explorer.Chain.SmartContract do
compiler_version: String.t(),
optimization: boolean,
contract_source_code: String.t(),
constructor_arguments: String.t() | nil,
evm_version: String.t() | nil,
optimization_runs: non_neg_integer() | nil,
abi: [function_description]
}
@ -207,6 +210,9 @@ defmodule Explorer.Chain.SmartContract do
field(:optimization, :boolean)
field(:contract_source_code, :string)
field(:constructor_arguments, :string)
field(:evm_version, :string)
field(:optimization_runs, :integer)
field(:external_libraries, :map)
field(:abi, {:array, :map})
has_many(
@ -239,7 +245,10 @@ defmodule Explorer.Chain.SmartContract do
:contract_source_code,
:address_hash,
:abi,
:constructor_arguments
:constructor_arguments,
:evm_version,
:optimization_runs,
:external_libraries
])
|> validate_required([:name, :compiler_version, :optimization, :contract_source_code, :abi, :address_hash])
|> unique_constraint(:address_hash)
@ -248,7 +257,16 @@ defmodule Explorer.Chain.SmartContract do
def invalid_contract_changeset(%__MODULE__{} = smart_contract, attrs, error) do
smart_contract
|> cast(attrs, [:name, :compiler_version, :optimization, :contract_source_code, :address_hash])
|> cast(attrs, [
:name,
:compiler_version,
:optimization,
:contract_source_code,
:address_hash,
:evm_version,
:optimization_runs,
:constructor_arguments
])
|> validate_required([:name, :compiler_version, :optimization, :address_hash])
|> add_error(:contract_source_code, error_message(error))
end

@ -68,9 +68,12 @@ defmodule Explorer.SmartContract.Publisher do
address_hash: address_hash,
name: params["name"],
compiler_version: params["compiler_version"],
evm_version: params["evm_version"],
optimization_runs: params["optimization_runs"],
optimization: params["optimization"],
contract_source_code: params["contract_source_code"],
constructor_arguments: clean_constructor_arguments,
external_libaries: params["external_libraries"],
abi: abi
}
end

@ -70,7 +70,7 @@ defmodule Explorer.SmartContract.Solidity.CodeCompiler do
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()
optimization_runs = optimization_runs(params)
evm_version = Keyword.get(params, :evm_version, List.last(allowed_evm_versions()))
external_libs = Keyword.get(params, :external_libs, %{})
@ -163,6 +163,16 @@ defmodule Explorer.SmartContract.Solidity.CodeCompiler do
defp optimize_value(true), do: "1"
defp optimize_value("true"), do: "1"
defp optimization_runs(params) do
value = params |> Keyword.get(:optimization_runs, "200")
if is_binary(value) do
value
else
"#{value}"
end
end
defp create_source_file(source) do
{:ok, path} = Briefly.create()

@ -0,0 +1,11 @@
defmodule Explorer.Repo.Migrations.AddAdditionalContractFields do
use Ecto.Migration
def change do
alter table(:smart_contracts) do
add(:optimization_runs, :integer, null: true)
add(:evm_version, :string, null: true)
add(:external_libraries, :jsonb, null: true)
end
end
end
Loading…
Cancel
Save