From dd2a8116452d14e862b6d55d7c13fdcb4ee042a2 Mon Sep 17 00:00:00 2001 From: Ayrat Badykov Date: Fri, 16 Aug 2019 16:17:07 +0300 Subject: [PATCH 1/8] add verification submission comment --- .../templates/address_contract/index.html.eex | 2 +- .../views/address_contract_view.ex | 9 +++++--- apps/explorer/lib/explorer/chain.ex | 22 +++++++++++++++++-- .../lib/explorer/chain/smart_contract.ex | 22 +++++++++++++++++++ 4 files changed, 49 insertions(+), 6 deletions(-) diff --git a/apps/block_scout_web/lib/block_scout_web/templates/address_contract/index.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/address_contract/index.html.eex index e8d6501e02..0b2f4f7574 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/address_contract/index.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/address_contract/index.html.eex @@ -66,7 +66,7 @@
-
<%= for {line, number} <- contract_lines_with_index(@address.smart_contract.contract_source_code) do %>
<%= line %>
<% end %>
+
<%= for {line, number} <- contract_lines_with_index(@address.smart_contract) do %>
<%= line %>
<% end %>
diff --git a/apps/block_scout_web/lib/block_scout_web/views/address_contract_view.ex b/apps/block_scout_web/lib/block_scout_web/views/address_contract_view.ex index 57c6e11da7..0ad32985c4 100644 --- a/apps/block_scout_web/lib/block_scout_web/views/address_contract_view.ex +++ b/apps/block_scout_web/lib/block_scout_web/views/address_contract_view.ex @@ -2,7 +2,7 @@ defmodule BlockScoutWeb.AddressContractView do use BlockScoutWeb, :view alias ABI.{FunctionSelector, TypeDecoder} - alias Explorer.Chain.{Address, Data, InternalTransaction} + alias Explorer.Chain.{Address, Data, InternalTransaction, SmartContract} def render("scripts.html", %{conn: conn}) do render_scripts(conn, "address_contract/code_highlighting.js") @@ -63,8 +63,11 @@ defmodule BlockScoutWeb.AddressContractView do end) end - def contract_lines_with_index(contract_source_code) do - contract_lines = String.split(contract_source_code, "\n") + def contract_lines_with_index(contract_contract) do + contract_lines = + contract_contract.contract_source_code + |> String.split("\n") + |> SmartContract.add_submitted_comment(contract_contract.inserted_at) max_digits = contract_lines diff --git a/apps/explorer/lib/explorer/chain.ex b/apps/explorer/lib/explorer/chain.ex index 58253c0f27..979e5975a8 100644 --- a/apps/explorer/lib/explorer/chain.ex +++ b/apps/explorer/lib/explorer/chain.ex @@ -2532,8 +2532,26 @@ defmodule Explorer.Chain do @spec address_hash_to_address_with_source_code(Hash.Address.t()) :: Address.t() | nil def address_hash_to_address_with_source_code(address_hash) do case Repo.get(Address, address_hash) do - nil -> nil - address -> Repo.preload(address, [:smart_contract, :decompiled_smart_contracts]) + nil -> + nil + + address -> + address_with_smart_contract = Repo.preload(address, [:smart_contract, :decompiled_smart_contracts]) + + if address_with_smart_contract.smart_contract do + formatted_code = + SmartContract.add_submitted_comment( + address_with_smart_contract.smart_contract.contract_source_code, + address_with_smart_contract.smart_contract.inserted_at + ) + + %{ + address_with_smart_contract + | smart_contract: %{address_with_smart_contract.smart_contract | contract_source_code: formatted_code} + } + else + address_with_smart_contract + end end end diff --git a/apps/explorer/lib/explorer/chain/smart_contract.ex b/apps/explorer/lib/explorer/chain/smart_contract.ex index ed579e8e00..e11e8a6d78 100644 --- a/apps/explorer/lib/explorer/chain/smart_contract.ex +++ b/apps/explorer/lib/explorer/chain/smart_contract.ex @@ -271,6 +271,28 @@ defmodule Explorer.Chain.SmartContract do |> add_error(:contract_source_code, error_message(error)) end + def add_submitted_comment(code, inserted_at) when is_binary(code) do + code + |> String.split("\n") + |> add_submitted_commet(inserted_at) + |> Enum.join("\n") + end + + def add_submitted_comment(contract_lines, inserted_at) when is_list(contract_lines) do + index = + Enum.find(contract_lines, fn line -> + String.contains?(line, "Submitted for verification at Etherscan.io") + end) + + if index do + List.replace_at(contract_lines, index, "* Submitted for verification at blockscout.com") + else + header = ["/**", "* Submitted for verification at blockscout.com on #{inserted_at}", "*/"] + + header ++ contract_lines + end + end + defp upsert_contract_methods(%Ecto.Changeset{changes: %{abi: abi}} = changeset) do ContractMethod.upsert_from_abi(abi, get_field(changeset, :address_hash)) From 5d035b9a0256efdc41ea4f949c62eeb9dfc2094a Mon Sep 17 00:00:00 2001 From: Ayrat Badykov Date: Fri, 16 Aug 2019 16:21:33 +0300 Subject: [PATCH 2/8] fix typo --- apps/explorer/lib/explorer/chain/smart_contract.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/explorer/lib/explorer/chain/smart_contract.ex b/apps/explorer/lib/explorer/chain/smart_contract.ex index e11e8a6d78..7a88110f71 100644 --- a/apps/explorer/lib/explorer/chain/smart_contract.ex +++ b/apps/explorer/lib/explorer/chain/smart_contract.ex @@ -274,7 +274,7 @@ defmodule Explorer.Chain.SmartContract do def add_submitted_comment(code, inserted_at) when is_binary(code) do code |> String.split("\n") - |> add_submitted_commet(inserted_at) + |> add_submitted_comment(inserted_at) |> Enum.join("\n") end From 01ab9a5a317efb6d3bc96c68c0cba4506a35406f Mon Sep 17 00:00:00 2001 From: Ayrat Badykov Date: Fri, 16 Aug 2019 16:22:53 +0300 Subject: [PATCH 3/8] add CHANGELOG entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f006769dbf..a58616d9bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ ## Current ### Features +- [#1588](https://github.com/poanetwork/blockscout/pull/2588) - add verification submission comment - [#2561](https://github.com/poanetwork/blockscout/pull/2561) - Add token's type to the response of tokenlist method - [#2499](https://github.com/poanetwork/blockscout/pull/2499) - import emission reward ranges - [#2497](https://github.com/poanetwork/blockscout/pull/2497) - Add generic Ordered Cache behaviour and implementation From c15c9bd70565c54f1502c514fd1cb3b7391f7a34 Mon Sep 17 00:00:00 2001 From: Ayrat Badykov Date: Fri, 16 Aug 2019 16:40:55 +0300 Subject: [PATCH 4/8] fix tests --- .../templates/address_contract/index.html.eex | 2 +- .../views/address_contract_view.ex | 6 +-- .../views/address_contract_view_test.exs | 47 ++++++++++++------- .../lib/explorer/chain/smart_contract.ex | 2 +- 4 files changed, 35 insertions(+), 22 deletions(-) diff --git a/apps/block_scout_web/lib/block_scout_web/templates/address_contract/index.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/address_contract/index.html.eex index 0b2f4f7574..1e98048169 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/address_contract/index.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/address_contract/index.html.eex @@ -66,7 +66,7 @@
-
<%= for {line, number} <- contract_lines_with_index(@address.smart_contract) do %>
<%= line %>
<% end %>
+
<%= for {line, number} <- contract_lines_with_index(@address.smart_contract.contract_source_code, @address.smart_contract.inserted_at) do %>
<%= line %>
<% end %>
diff --git a/apps/block_scout_web/lib/block_scout_web/views/address_contract_view.ex b/apps/block_scout_web/lib/block_scout_web/views/address_contract_view.ex index 0ad32985c4..f9128dfb11 100644 --- a/apps/block_scout_web/lib/block_scout_web/views/address_contract_view.ex +++ b/apps/block_scout_web/lib/block_scout_web/views/address_contract_view.ex @@ -63,11 +63,11 @@ defmodule BlockScoutWeb.AddressContractView do end) end - def contract_lines_with_index(contract_contract) do + def contract_lines_with_index(source_code, inserted_at \\ nil) do contract_lines = - contract_contract.contract_source_code + source_code |> String.split("\n") - |> SmartContract.add_submitted_comment(contract_contract.inserted_at) + |> SmartContract.add_submitted_comment(inserted_at) max_digits = contract_lines diff --git a/apps/block_scout_web/test/block_scout_web/views/address_contract_view_test.exs b/apps/block_scout_web/test/block_scout_web/views/address_contract_view_test.exs index 4bcb1eb2bf..9f0314fb88 100644 --- a/apps/block_scout_web/test/block_scout_web/views/address_contract_view_test.exs +++ b/apps/block_scout_web/test/block_scout_web/views/address_contract_view_test.exs @@ -38,22 +38,25 @@ defmodule BlockScoutWeb.AddressContractViewTest do result = AddressContractView.contract_lines_with_index(code) assert result == [ - {"pragma solidity >=0.4.22 <0.6.0;", " 1"}, - {"", " 2"}, - {"struct Proposal {", " 3"}, - {" uint voteCount;", " 4"}, - {"}", " 5"}, - {"", " 6"}, - {"address chairperson;", " 7"}, - {"mapping(address => Voter) voters;", " 8"}, - {"Proposal[] proposals;", " 9"}, - {"", "10"}, - {"constructor(uint8 _numProposals) public {", "11"}, - {" chairperson = msg.sender;", "12"}, - {" voters[chairperson].weight = 1;", "13"}, - {" proposals.length = _numProposals;", "14"}, - {"}", "15"}, - {"", "16"} + {"/**", " 1"}, + {"* Submitted for verification at blockscout.com on ", " 2"}, + {"*/", " 3"}, + {"pragma solidity >=0.4.22 <0.6.0;", " 4"}, + {"", " 5"}, + {"struct Proposal {", " 6"}, + {" uint voteCount;", " 7"}, + {"}", " 8"}, + {"", " 9"}, + {"address chairperson;", "10"}, + {"mapping(address => Voter) voters;", "11"}, + {"Proposal[] proposals;", "12"}, + {"", "13"}, + {"constructor(uint8 _numProposals) public {", "14"}, + {" chairperson = msg.sender;", "15"}, + {" voters[chairperson].weight = 1;", "16"}, + {" proposals.length = _numProposals;", "17"}, + {"}", "18"}, + {"", "19"} ] end @@ -66,7 +69,17 @@ defmodule BlockScoutWeb.AddressContractViewTest do test "returns a list of tuples and the first element is just a line from the original string" do result = AddressContractView.contract_lines_with_index("a\nb\nc\nd\ne") - assert Enum.map(result, fn {line, _number} -> line end) == ["a", "b", "c", "d", "e"] + + assert Enum.map(result, fn {line, _number} -> line end) == [ + "/**", + "* Submitted for verification at blockscout.com on ", + "*/", + "a", + "b", + "c", + "d", + "e" + ] end end end diff --git a/apps/explorer/lib/explorer/chain/smart_contract.ex b/apps/explorer/lib/explorer/chain/smart_contract.ex index 7a88110f71..bbddd51100 100644 --- a/apps/explorer/lib/explorer/chain/smart_contract.ex +++ b/apps/explorer/lib/explorer/chain/smart_contract.ex @@ -285,7 +285,7 @@ defmodule Explorer.Chain.SmartContract do end) if index do - List.replace_at(contract_lines, index, "* Submitted for verification at blockscout.com") + List.replace_at(contract_lines, index, "* Submitted for verification at blockscout.com on #{inserted_at}") else header = ["/**", "* Submitted for verification at blockscout.com on #{inserted_at}", "*/"] From cb3cc8eb65bcd942cc0a9deaa47248838e42d5c6 Mon Sep 17 00:00:00 2001 From: Ayrat Badykov Date: Mon, 19 Aug 2019 10:54:01 +0300 Subject: [PATCH 5/8] fix api/rpc/contract_controller_test --- .../api/rpc/contract_controller_test.exs | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/apps/block_scout_web/test/block_scout_web/controllers/api/rpc/contract_controller_test.exs b/apps/block_scout_web/test/block_scout_web/controllers/api/rpc/contract_controller_test.exs index e070cf8e57..af9daffed8 100644 --- a/apps/block_scout_web/test/block_scout_web/controllers/api/rpc/contract_controller_test.exs +++ b/apps/block_scout_web/test/block_scout_web/controllers/api/rpc/contract_controller_test.exs @@ -1,6 +1,6 @@ defmodule BlockScoutWeb.API.RPC.ContractControllerTest do use BlockScoutWeb.ConnCase - alias Explorer.Factory + alias Explorer.{Chain, Factory} describe "listcontracts" do setup do @@ -422,7 +422,9 @@ defmodule BlockScoutWeb.API.RPC.ContractControllerTest do expected_result = [ %{ "Address" => to_string(contract.address_hash), - "SourceCode" => contract.contract_source_code, + "SourceCode" => + "/**\n* Submitted for verification at blockscout.com on #{contract.inserted_at}\n*/\n" <> + contract.contract_source_code, "ABI" => Jason.encode!(contract.abi), "ContractName" => contract.name, "CompilerVersion" => contract.compiler_version, @@ -467,9 +469,13 @@ defmodule BlockScoutWeb.API.RPC.ContractControllerTest do |> get("/api", params) |> json_response(200) + verified_contract = Chain.address_hash_to_smart_contract(contract_address.hash) + expected_result = %{ "Address" => to_string(contract_address.hash), - "SourceCode" => contract_code_info.source_code, + "SourceCode" => + "/**\n* Submitted for verification at blockscout.com on #{verified_contract.inserted_at}\n*/\n" <> + contract_code_info.source_code, "ABI" => Jason.encode!(contract_code_info.abi), "ContractName" => contract_code_info.name, "CompilerVersion" => contract_code_info.version, @@ -533,8 +539,14 @@ defmodule BlockScoutWeb.API.RPC.ContractControllerTest do result = response["result"] + verified_contract = Chain.address_hash_to_smart_contract(contract_address.hash) + assert result["Address"] == to_string(contract_address.hash) - assert result["SourceCode"] == contract_source_code + + assert result["SourceCode"] == + "/**\n* Submitted for verification at blockscout.com on #{verified_contract.inserted_at}\n*/\n" <> + contract_source_code + assert result["ContractName"] == name assert result["DecompiledSourceCode"] == "Contract source code not decompiled." assert result["DecompilerVersion"] == "" From e73280aafcc5e561d03307f66ad2802e9c38086a Mon Sep 17 00:00:00 2001 From: Ayrat Badykov Date: Mon, 19 Aug 2019 14:48:36 +0300 Subject: [PATCH 6/8] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a58616d9bb..203f2dcce1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ ## Current ### Features -- [#1588](https://github.com/poanetwork/blockscout/pull/2588) - add verification submission comment +- [#2588](https://github.com/poanetwork/blockscout/pull/2588) - add verification submission comment - [#2561](https://github.com/poanetwork/blockscout/pull/2561) - Add token's type to the response of tokenlist method - [#2499](https://github.com/poanetwork/blockscout/pull/2499) - import emission reward ranges - [#2497](https://github.com/poanetwork/blockscout/pull/2497) - Add generic Ordered Cache behaviour and implementation From f28e866f8fd766d91bb8d6d63a8f42214d5c2e9d Mon Sep 17 00:00:00 2001 From: Ayrat Badykov Date: Mon, 2 Sep 2019 11:27:45 +0300 Subject: [PATCH 7/8] check if blockscout comment is already added --- .../lib/explorer/chain/smart_contract.ex | 29 +++++++++++++++---- 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/apps/explorer/lib/explorer/chain/smart_contract.ex b/apps/explorer/lib/explorer/chain/smart_contract.ex index bbddd51100..a3c198c642 100644 --- a/apps/explorer/lib/explorer/chain/smart_contract.ex +++ b/apps/explorer/lib/explorer/chain/smart_contract.ex @@ -279,17 +279,34 @@ defmodule Explorer.Chain.SmartContract do end def add_submitted_comment(contract_lines, inserted_at) when is_list(contract_lines) do - index = + etherscan_index = Enum.find(contract_lines, fn line -> String.contains?(line, "Submitted for verification at Etherscan.io") end) - if index do - List.replace_at(contract_lines, index, "* Submitted for verification at blockscout.com on #{inserted_at}") - else - header = ["/**", "* Submitted for verification at blockscout.com on #{inserted_at}", "*/"] + blockscout_index = + Enum.find(contract_lines, fn line -> + String.contains?(line, "Submitted for verification at blockscout.com") + end) + + cond do + etherscan_index && blockscout_index -> + List.replace_at(contract_lines, etherscan_index, "*") + + etherscan_index && !blockscout_index -> + List.replace_at( + contract_lines, + etherscan_index, + "* Submitted for verification at blockscout.com on #{inserted_at}" + ) + + !etherscan_index && !blockscout_index -> + header = ["/**", "* Submitted for verification at blockscout.com on #{inserted_at}", "*/"] + + header ++ contract_lines - header ++ contract_lines + true -> + contract_lines end end From 327b762528f5fbffb478ee5aead16c276725eef4 Mon Sep 17 00:00:00 2001 From: Ayrat Badykov Date: Tue, 3 Sep 2019 12:56:38 +0300 Subject: [PATCH 8/8] find index of the comment instead of item --- apps/explorer/lib/explorer/chain/smart_contract.ex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/explorer/lib/explorer/chain/smart_contract.ex b/apps/explorer/lib/explorer/chain/smart_contract.ex index a3c198c642..0db7d7e613 100644 --- a/apps/explorer/lib/explorer/chain/smart_contract.ex +++ b/apps/explorer/lib/explorer/chain/smart_contract.ex @@ -280,12 +280,12 @@ defmodule Explorer.Chain.SmartContract do def add_submitted_comment(contract_lines, inserted_at) when is_list(contract_lines) do etherscan_index = - Enum.find(contract_lines, fn line -> + Enum.find_index(contract_lines, fn line -> String.contains?(line, "Submitted for verification at Etherscan.io") end) blockscout_index = - Enum.find(contract_lines, fn line -> + Enum.find_index(contract_lines, fn line -> String.contains?(line, "Submitted for verification at blockscout.com") end)