Skip to content

Commit

Permalink
feat: add an admin method to import contract methods.
Browse files Browse the repository at this point in the history
  • Loading branch information
zachdaniel committed Mar 5, 2019
1 parent 434b445 commit b9ade78
Show file tree
Hide file tree
Showing 8 changed files with 128 additions and 2 deletions.
2 changes: 2 additions & 0 deletions apps/block_scout_web/assets/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ import './pages/pending_transactions'
import './pages/transaction'
import './pages/transactions'

import './pages/admin/tasks.js'

import './lib/clipboard_buttons'
import './lib/currency'
import './lib/from_now'
Expand Down
26 changes: 26 additions & 0 deletions apps/block_scout_web/assets/js/pages/admin/tasks.js
Original file line number Diff line number Diff line change
@@ -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)
4 changes: 4 additions & 0 deletions apps/block_scout_web/lib/block_scout_web/admin_router.ex
Original file line number Diff line number Diff line change
Expand Up @@ -43,5 +43,9 @@ defmodule BlockScoutWeb.AdminRouter do
pipe_through([:browser, :check_configured, :ensure_admin])

get("/", DashboardController, :index)

scope "/tasks" do
get("/create_contract_methods", TaskController, :create_contract_methods, as: :create_contract_methods)
end
end
end
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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>
10 changes: 10 additions & 0 deletions apps/block_scout_web/priv/gettext/default.pot
Original file line number Diff line number Diff line change
Expand Up @@ -1671,3 +1671,13 @@ msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:131
msgid "UTF-8"
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 ""
10 changes: 10 additions & 0 deletions apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po
Original file line number Diff line number Diff line change
Expand Up @@ -1671,3 +1671,13 @@ msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:131
msgid "UTF-8"
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 ""
19 changes: 18 additions & 1 deletion apps/explorer/lib/explorer/chain/contract_method.ex
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ defmodule Explorer.Chain.ContractMethod do

use Explorer.Schema

alias Explorer.Chain.{Hash, MethodIdentifier}
alias Explorer.Chain.{Hash, MethodIdentifier, SmartContract}
alias Explorer.Repo

@type t :: %__MODULE__{
Expand Down Expand Up @@ -49,6 +49,23 @@ defmodule Explorer.Chain.ContractMethod do
Repo.insert_all(__MODULE__, successes, on_conflict: :nothing, conflict_target: [:identifier, :abi])
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
case ABI.parse_specification([element], include_events?: true) do
[selector] ->
Expand Down

0 comments on commit b9ade78

Please sign in to comment.