feat: add an admin method to import contract methods.

pull/1519/head
zachdaniel 6 years ago
parent 434b4455a1
commit b9ade785d2
  1. 2
      apps/block_scout_web/assets/js/app.js
  2. 26
      apps/block_scout_web/assets/js/pages/admin/tasks.js
  3. 4
      apps/block_scout_web/lib/block_scout_web/admin_router.ex
  4. 22
      apps/block_scout_web/lib/block_scout_web/controllers/admin/tasks_controller.ex
  5. 37
      apps/block_scout_web/lib/block_scout_web/templates/admin/dashboard/index.html.eex
  6. 10
      apps/block_scout_web/priv/gettext/default.pot
  7. 10
      apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po
  8. 19
      apps/explorer/lib/explorer/chain/contract_method.ex

@ -31,6 +31,8 @@ import './pages/pending_transactions'
import './pages/transaction' import './pages/transaction'
import './pages/transactions' import './pages/transactions'
import './pages/admin/tasks.js'
import './lib/clipboard_buttons' import './lib/clipboard_buttons'
import './lib/currency' import './lib/currency'
import './lib/from_now' import './lib/from_now'

@ -0,0 +1,26 @@
import $ from 'jquery'
const runTask = (event) => {
const element = event.currentTarget
const $element = $(element)
const $loading = $element.find('[data-loading-message]')
const $errorMessage = $element.find('[data-error-message]')
const $successMessage = $element.find('[data-success-message]')
const apiPath = element.dataset.api_path
$errorMessage.hide()
$successMessage.hide()
$loading.show()
$.get(apiPath)
.done(response => {
$successMessage.show()
$loading.hide()
})
.fail(() => {
$loading.hide()
$errorMessage.show()
})
}
$('#run-create-contract-methods').click(runTask)

@ -43,5 +43,9 @@ defmodule BlockScoutWeb.AdminRouter do
pipe_through([:browser, :check_configured, :ensure_admin]) pipe_through([:browser, :check_configured, :ensure_admin])
get("/", DashboardController, :index) get("/", DashboardController, :index)
scope "/tasks" do
get("/create_contract_methods", TaskController, :create_contract_methods, as: :create_contract_methods)
end
end end
end end

@ -0,0 +1,22 @@
defmodule BlockScoutWeb.Admin.TaskController do
use BlockScoutWeb, :controller
require Logger
alias Explorer.Chain.ContractMethod
@ok_resp Poison.encode!(%{status: "success"})
@not_ok_resp Poison.encode!(%{status: "failure"})
def create_contract_methods(conn, _) do
case ContractMethod.import_all() do
:ok ->
send_resp(conn, 200, Poison.encode!(@ok_resp))
{:error, error} ->
Logger.error(fn -> ["Something went wrong while creating contract methods: ", inspect(error)] end)
send_resp(conn, 500, Poison.encode!(@not_ok_resp))
end
end
end

@ -1 +1,36 @@
<div data-test="administrator_dashboard"></div> <div data-test="administrator_dashboard">
<div class="container">
<div class="row">
<h2>Tasks</h2>
</div>
<div class="row">
<div class="col-sm-6">
<div class="card">
<div class="card-body">
<div class="card-title">
<h3>Create Contract Methods</h3>
</div>
<div class="card-text">
<p>
<%= gettext("For any existing contracts in the database, insert all ABI entries into the contract_methods table. Use this in case you have verified smart contracts before early March 2019 and you want other contracts with the same functions to show those ABI's as candidate matches.") %>
</p>
</div>
<button id="run-create-contract-methods" data-api_path="<%= BlockScoutWeb.AdminRouter.Helpers.create_contract_methods_path(@conn, :create_contract_methods) %>" class="btn btn-primary">
<%= gettext("Run") %>
<span data-loading-message class="loading-spinner-small mr-2" style="display: none;">
<span class="loading-spinner-block-1"></span>
<span class="loading-spinner-block-2"></span>
</span>
<span data-success-message style="display: none;"> - Success</span>
<span data-error-message style="display: none;"> - Failed</span>
</button>
</div>
</div>
</div>
</div>
</div>
</div>

@ -1671,3 +1671,13 @@ msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:131 #: lib/block_scout_web/templates/transaction/overview.html.eex:131
msgid "UTF-8" msgid "UTF-8"
msgstr "" msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/admin/dashboard/index.html.eex:16
msgid "For any existing contracts in the database, insert all ABI entries into the contract_methods table. Use this in case you have verified smart contracts before early March 2019 and you want other contracts with the same functions to show those ABI's as candidate matches."
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/admin/dashboard/index.html.eex:21
msgid "Run"
msgstr ""

@ -1671,3 +1671,13 @@ msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:131 #: lib/block_scout_web/templates/transaction/overview.html.eex:131
msgid "UTF-8" msgid "UTF-8"
msgstr "" msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/admin/dashboard/index.html.eex:16
msgid "For any existing contracts in the database, insert all ABI entries into the contract_methods table. Use this in case you have verified smart contracts before early March 2019 and you want other contracts with the same functions to show those ABI's as candidate matches."
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/admin/dashboard/index.html.eex:21
msgid "Run"
msgstr ""

@ -7,7 +7,7 @@ defmodule Explorer.Chain.ContractMethod do
use Explorer.Schema use Explorer.Schema
alias Explorer.Chain.{Hash, MethodIdentifier} alias Explorer.Chain.{Hash, MethodIdentifier, SmartContract}
alias Explorer.Repo alias Explorer.Repo
@type t :: %__MODULE__{ @type t :: %__MODULE__{
@ -49,6 +49,23 @@ defmodule Explorer.Chain.ContractMethod do
Repo.insert_all(__MODULE__, successes, on_conflict: :nothing, conflict_target: [:identifier, :abi]) Repo.insert_all(__MODULE__, successes, on_conflict: :nothing, conflict_target: [:identifier, :abi])
end end
def import_all do
result =
Repo.transaction(fn ->
SmartContract
|> Repo.stream()
|> Task.async_stream(fn contract ->
upsert_from_abi(contract.abi, contract.address_hash)
end)
|> Stream.run()
end)
case result do
{:ok, _} -> :ok
{:error, error} -> {:error, error}
end
end
defp abi_element_to_contract_method(element) do defp abi_element_to_contract_method(element) do
case ABI.parse_specification([element], include_events?: true) do case ABI.parse_specification([element], include_events?: true) do
[selector] -> [selector] ->

Loading…
Cancel
Save