diff --git a/apps/block_scout_web/assets/css/app.scss b/apps/block_scout_web/assets/css/app.scss
index f83c741bc0..3c722e8ec9 100644
--- a/apps/block_scout_web/assets/css/app.scss
+++ b/apps/block_scout_web/assets/css/app.scss
@@ -81,6 +81,7 @@ $fa-font-path: "~@fortawesome/fontawesome-free/webfonts";
@import "components/token_tile_view_more";
@import "components/dropdown";
@import "components/loading-spinner";
+@import "components/transaction-input";
:export {
primary: $primary;
diff --git a/apps/block_scout_web/assets/css/components/_transaction-input.scss b/apps/block_scout_web/assets/css/components/_transaction-input.scss
new file mode 100644
index 0000000000..63c3a847b8
--- /dev/null
+++ b/apps/block_scout_web/assets/css/components/_transaction-input.scss
@@ -0,0 +1,9 @@
+.raw-transaction-input{
+ display: none;
+}
+
+.transaction-input-text{
+ resize: vertical;
+ overflow: auto;
+ word-break: break-all;
+}
diff --git a/apps/block_scout_web/assets/js/app.js b/apps/block_scout_web/assets/js/app.js
index 83e3080c5c..b994bef9ef 100644
--- a/apps/block_scout_web/assets/js/app.js
+++ b/apps/block_scout_web/assets/js/app.js
@@ -44,3 +44,4 @@ import './lib/token_balance_dropdown_search'
import './lib/token_transfers_toggle'
import './lib/tooltip'
import './lib/try_api'
+import './lib/swappable_item'
diff --git a/apps/block_scout_web/assets/js/lib/clipboard_buttons.js b/apps/block_scout_web/assets/js/lib/clipboard_buttons.js
index d53851c84f..e195a68d0b 100644
--- a/apps/block_scout_web/assets/js/lib/clipboard_buttons.js
+++ b/apps/block_scout_web/assets/js/lib/clipboard_buttons.js
@@ -5,11 +5,14 @@ const clipboard = new ClipboardJS('[data-clipboard-text]')
clipboard.on('success', ({trigger}) => {
const copyButton = $(trigger)
+ copyButton.tooltip('dispose')
+
copyButton.tooltip({
title: 'Copied!',
trigger: 'click',
placement: 'top'
}).tooltip('show')
+
setTimeout(() => {
copyButton.tooltip('dispose')
}, 1000)
diff --git a/apps/block_scout_web/assets/js/lib/swappable_item.js b/apps/block_scout_web/assets/js/lib/swappable_item.js
new file mode 100644
index 0000000000..866b416299
--- /dev/null
+++ b/apps/block_scout_web/assets/js/lib/swappable_item.js
@@ -0,0 +1,21 @@
+import $ from 'jquery'
+
+const swapItems = (element, event) => {
+ const $element = $(element)
+ const item = $element.parent().closest('[swappable-item]')
+ const next = item.nextAll('[swappable-item]:first')
+
+ item.hide()
+
+ if (next.length) {
+ next.show()
+ } else {
+ item.parent().find('[swappable-item]:first').show()
+ }
+
+ return false
+}
+
+$('[swappable-item] [swapper]').on('click', function (event) {
+ swapItems(this, event)
+})
diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/transaction_internal_transaction_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/transaction_internal_transaction_controller.ex
index c8131220d4..58b5dfb75d 100644
--- a/apps/block_scout_web/lib/block_scout_web/controllers/transaction_internal_transaction_controller.ex
+++ b/apps/block_scout_web/lib/block_scout_web/controllers/transaction_internal_transaction_controller.ex
@@ -16,6 +16,7 @@ defmodule BlockScoutWeb.TransactionInternalTransactionController do
[created_contract_address: :names] => :optional,
[from_address: :names] => :optional,
[to_address: :names] => :optional,
+ [to_address: :smart_contract] => :optional,
:token_transfers => :optional
}
) do
diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/transaction_log_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/transaction_log_controller.ex
index be3567f47c..b07386bcaa 100644
--- a/apps/block_scout_web/lib/block_scout_web/controllers/transaction_log_controller.ex
+++ b/apps/block_scout_web/lib/block_scout_web/controllers/transaction_log_controller.ex
@@ -16,6 +16,7 @@ defmodule BlockScoutWeb.TransactionLogController do
[created_contract_address: :names] => :optional,
[from_address: :names] => :required,
[to_address: :names] => :optional,
+ [to_address: :smart_contract] => :optional,
:token_transfers => :optional
}
) do
diff --git a/apps/block_scout_web/lib/block_scout_web/templates/transaction/overview.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/transaction/overview.html.eex
index 6bafe04a3b..21440d0c8b 100644
--- a/apps/block_scout_web/lib/block_scout_web/templates/transaction/overview.html.eex
+++ b/apps/block_scout_web/lib/block_scout_web/templates/transaction/overview.html.eex
@@ -76,14 +76,100 @@
- - <%= gettext "Input" %>
- -
-
-
-<%= @transaction.input %>
-
+ <%= case decoded_input_data(@transaction) do %>
+ <% {:error, :contract_not_verified} -> %>
+
- <%= gettext "Input" %>
+
-
+
+
+ <% {:error, :could_not_decode} -> %>
+
- <%= gettext "Input" %>
+
-
+
+ Failed to decode input data. Some dynamic types are not currently supported.
+
+
+ <% {:ok, method_id, text, mapping} -> %>
+
- <%= gettext "Input" %>
+
-
+
+
+ Method Id |
+ 0x<%= method_id %> |
+
+
+ Call |
+ <%= text %> |
+
+
+
+
+ # |
+ Name |
+ Type |
+ Data |
+ |
+
+ <%= for {{name, type, value}, index} <- Enum.with_index(mapping) do %>
+
+ <%= index %> |
+ <%= name %> |
+ <%= type %> |
+ <%= case type do %>
+ <% "address" -> %>
+ <% address = "0x" <> Base.encode16(value, case: :lower) %>
+
+
+ |
+
+
+ |
+
+ <% _ -> %>
+
+ <%= value %>
+ |
+
+
+ |
+ <% end %>
+
+ <% end %>
+
+
+ <% _ -> %>
+ <%= nil %>
+ <% end %>
+
+ <%= unless @transaction.input.bytes in [<<>>, nil] do %>
+
- <%= gettext "Raw Input" %>
+
-
+
+
-
+
+
+ <% end %>
diff --git a/apps/block_scout_web/lib/block_scout_web/views/transaction_view.ex b/apps/block_scout_web/lib/block_scout_web/views/transaction_view.ex
index 2f0d75d90c..6f630668b4 100644
--- a/apps/block_scout_web/lib/block_scout_web/views/transaction_view.ex
+++ b/apps/block_scout_web/lib/block_scout_web/views/transaction_view.ex
@@ -73,6 +73,10 @@ defmodule BlockScoutWeb.TransactionView do
Cldr.Number.to_string!(gas)
end
+ def decoded_input_data(transaction) do
+ Transaction.decoded_input_data(transaction)
+ end
+
@doc """
Converts a transaction's gas price to a displayable value.
"""
diff --git a/apps/block_scout_web/priv/gettext/default.pot b/apps/block_scout_web/priv/gettext/default.pot
index 6efd8d30f6..d52ded6643 100644
--- a/apps/block_scout_web/priv/gettext/default.pot
+++ b/apps/block_scout_web/priv/gettext/default.pot
@@ -283,12 +283,12 @@ msgid "Contract Address Pending"
msgstr ""
#, elixir-format
-#: lib/block_scout_web/views/transaction_view.ex:127
+#: lib/block_scout_web/views/transaction_view.ex:131
msgid "Contract Call"
msgstr ""
#, elixir-format
-#: lib/block_scout_web/views/transaction_view.ex:126
+#: lib/block_scout_web/views/transaction_view.ex:130
msgid "Contract Creation"
msgstr ""
@@ -403,7 +403,7 @@ msgstr ""
#: lib/block_scout_web/templates/internal_transaction/_tile.html.eex:16
#: lib/block_scout_web/templates/transaction/_pending_tile.html.eex:19
#: lib/block_scout_web/templates/transaction/_tile.html.eex:26
-#: lib/block_scout_web/templates/transaction/overview.html.eex:96
+#: lib/block_scout_web/templates/transaction/overview.html.eex:182
#: lib/block_scout_web/views/wei_helpers.ex:72
msgid "Ether"
msgstr ""
@@ -442,7 +442,7 @@ msgid "GET"
msgstr ""
#, elixir-format
-#: lib/block_scout_web/templates/transaction/overview.html.eex:109
+#: lib/block_scout_web/templates/transaction/overview.html.eex:195
msgid "Gas"
msgstr ""
@@ -486,7 +486,9 @@ msgid "Indexing Tokens"
msgstr ""
#, elixir-format
-#: lib/block_scout_web/templates/transaction/overview.html.eex:79
+#: lib/block_scout_web/templates/transaction/overview.html.eex:81
+#: lib/block_scout_web/templates/transaction/overview.html.eex:88
+#: lib/block_scout_web/templates/transaction/overview.html.eex:95
msgid "Input"
msgstr ""
@@ -505,7 +507,7 @@ msgstr ""
#: lib/block_scout_web/templates/transaction/_tabs.html.eex:43
#: lib/block_scout_web/templates/transaction_internal_transaction/index.html.eex:10
#: lib/block_scout_web/views/address_view.ex:213
-#: lib/block_scout_web/views/transaction_view.ex:176
+#: lib/block_scout_web/views/transaction_view.ex:180
msgid "Internal Transactions"
msgstr ""
@@ -523,7 +525,7 @@ msgid "Less than"
msgstr ""
#, elixir-format
-#: lib/block_scout_web/templates/transaction/overview.html.eex:121
+#: lib/block_scout_web/templates/transaction/overview.html.eex:207
msgid "Limit"
msgstr ""
@@ -531,7 +533,7 @@ msgstr ""
#: lib/block_scout_web/templates/transaction/_tabs.html.eex:21
#: lib/block_scout_web/templates/transaction/_tabs.html.eex:48
#: lib/block_scout_web/templates/transaction_log/index.html.eex:10
-#: lib/block_scout_web/views/transaction_view.ex:177
+#: lib/block_scout_web/views/transaction_view.ex:181
msgid "Logs"
msgstr ""
@@ -680,7 +682,7 @@ msgstr ""
#: lib/block_scout_web/templates/layout/_topnav.html.eex:44
#: lib/block_scout_web/templates/transaction/overview.html.eex:54
#: lib/block_scout_web/views/transaction_view.ex:57
-#: lib/block_scout_web/views/transaction_view.ex:83
+#: lib/block_scout_web/views/transaction_view.ex:87
msgid "Pending"
msgstr ""
@@ -896,7 +898,7 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/tokens/transfer/_token_transfer.html.eex:4
#: lib/block_scout_web/templates/transaction_token_transfer/_token_transfer.html.eex:4
-#: lib/block_scout_web/views/transaction_view.ex:125
+#: lib/block_scout_web/views/transaction_view.ex:129
msgid "Token Transfer"
msgstr ""
@@ -908,7 +910,7 @@ msgstr ""
#: lib/block_scout_web/templates/transaction/_tabs.html.eex:36
#: lib/block_scout_web/templates/transaction_token_transfer/index.html.eex:10
#: lib/block_scout_web/views/tokens/overview_view.ex:35
-#: lib/block_scout_web/views/transaction_view.ex:175
+#: lib/block_scout_web/views/transaction_view.ex:179
msgid "Token Transfers"
msgstr ""
@@ -950,7 +952,7 @@ msgid "Total transactions"
msgstr ""
#, elixir-format
-#: lib/block_scout_web/views/transaction_view.ex:128
+#: lib/block_scout_web/views/transaction_view.ex:132
msgid "Transaction"
msgstr ""
@@ -1018,7 +1020,7 @@ msgid "Unique Token"
msgstr ""
#, elixir-format
-#: lib/block_scout_web/templates/transaction/overview.html.eex:114
+#: lib/block_scout_web/templates/transaction/overview.html.eex:200
msgid "Used"
msgstr ""
@@ -1039,7 +1041,7 @@ msgid "Validations"
msgstr ""
#, elixir-format
-#: lib/block_scout_web/templates/transaction/overview.html.eex:96
+#: lib/block_scout_web/templates/transaction/overview.html.eex:182
msgid "Value"
msgstr ""
@@ -1216,3 +1218,20 @@ msgstr ""
#: lib/block_scout_web/templates/api_docs/index.html.eex:7
msgid "This API is provided for developers transitioning their applications from Etherscan to BlockScout. It supports GET and POST requests."
msgstr ""
+
+#, elixir-format
+#: lib/block_scout_web/templates/transaction/overview.html.eex:153
+msgid "Raw Input"
+msgstr ""
+
+#, elixir-format
+#: lib/block_scout_web/templates/transaction/overview.html.eex:156
+msgid "Show Raw Input"
+msgstr ""
+
+#, elixir-format
+#: lib/block_scout_web/templates/transaction/overview.html.eex:130
+#: lib/block_scout_web/templates/transaction/overview.html.eex:140
+#: lib/block_scout_web/templates/transaction/overview.html.eex:164
+msgid "copy"
+msgstr ""
diff --git a/apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po b/apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po
index 22b5201e98..a4ad8ee9db 100644
--- a/apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po
+++ b/apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po
@@ -283,12 +283,12 @@ msgid "Contract Address Pending"
msgstr ""
#, elixir-format
-#: lib/block_scout_web/views/transaction_view.ex:127
+#: lib/block_scout_web/views/transaction_view.ex:131
msgid "Contract Call"
msgstr ""
#, elixir-format
-#: lib/block_scout_web/views/transaction_view.ex:126
+#: lib/block_scout_web/views/transaction_view.ex:130
msgid "Contract Creation"
msgstr ""
@@ -403,7 +403,7 @@ msgstr ""
#: lib/block_scout_web/templates/internal_transaction/_tile.html.eex:16
#: lib/block_scout_web/templates/transaction/_pending_tile.html.eex:19
#: lib/block_scout_web/templates/transaction/_tile.html.eex:26
-#: lib/block_scout_web/templates/transaction/overview.html.eex:96
+#: lib/block_scout_web/templates/transaction/overview.html.eex:182
#: lib/block_scout_web/views/wei_helpers.ex:72
msgid "Ether"
msgstr "POA"
@@ -442,7 +442,7 @@ msgid "GET"
msgstr ""
#, elixir-format
-#: lib/block_scout_web/templates/transaction/overview.html.eex:109
+#: lib/block_scout_web/templates/transaction/overview.html.eex:195
msgid "Gas"
msgstr ""
@@ -486,7 +486,9 @@ msgid "Indexing Tokens"
msgstr ""
#, elixir-format
-#: lib/block_scout_web/templates/transaction/overview.html.eex:79
+#: lib/block_scout_web/templates/transaction/overview.html.eex:81
+#: lib/block_scout_web/templates/transaction/overview.html.eex:88
+#: lib/block_scout_web/templates/transaction/overview.html.eex:95
msgid "Input"
msgstr ""
@@ -505,7 +507,7 @@ msgstr ""
#: lib/block_scout_web/templates/transaction/_tabs.html.eex:43
#: lib/block_scout_web/templates/transaction_internal_transaction/index.html.eex:10
#: lib/block_scout_web/views/address_view.ex:213
-#: lib/block_scout_web/views/transaction_view.ex:176
+#: lib/block_scout_web/views/transaction_view.ex:180
msgid "Internal Transactions"
msgstr ""
@@ -523,7 +525,7 @@ msgid "Less than"
msgstr ""
#, elixir-format
-#: lib/block_scout_web/templates/transaction/overview.html.eex:121
+#: lib/block_scout_web/templates/transaction/overview.html.eex:207
msgid "Limit"
msgstr ""
@@ -531,7 +533,7 @@ msgstr ""
#: lib/block_scout_web/templates/transaction/_tabs.html.eex:21
#: lib/block_scout_web/templates/transaction/_tabs.html.eex:48
#: lib/block_scout_web/templates/transaction_log/index.html.eex:10
-#: lib/block_scout_web/views/transaction_view.ex:177
+#: lib/block_scout_web/views/transaction_view.ex:181
msgid "Logs"
msgstr ""
@@ -680,7 +682,7 @@ msgstr ""
#: lib/block_scout_web/templates/layout/_topnav.html.eex:44
#: lib/block_scout_web/templates/transaction/overview.html.eex:54
#: lib/block_scout_web/views/transaction_view.ex:57
-#: lib/block_scout_web/views/transaction_view.ex:83
+#: lib/block_scout_web/views/transaction_view.ex:87
msgid "Pending"
msgstr ""
@@ -896,7 +898,7 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/tokens/transfer/_token_transfer.html.eex:4
#: lib/block_scout_web/templates/transaction_token_transfer/_token_transfer.html.eex:4
-#: lib/block_scout_web/views/transaction_view.ex:125
+#: lib/block_scout_web/views/transaction_view.ex:129
msgid "Token Transfer"
msgstr ""
@@ -908,7 +910,7 @@ msgstr ""
#: lib/block_scout_web/templates/transaction/_tabs.html.eex:36
#: lib/block_scout_web/templates/transaction_token_transfer/index.html.eex:10
#: lib/block_scout_web/views/tokens/overview_view.ex:35
-#: lib/block_scout_web/views/transaction_view.ex:175
+#: lib/block_scout_web/views/transaction_view.ex:179
msgid "Token Transfers"
msgstr ""
@@ -950,7 +952,7 @@ msgid "Total transactions"
msgstr ""
#, elixir-format
-#: lib/block_scout_web/views/transaction_view.ex:128
+#: lib/block_scout_web/views/transaction_view.ex:132
msgid "Transaction"
msgstr ""
@@ -1018,7 +1020,7 @@ msgid "Unique Token"
msgstr ""
#, elixir-format
-#: lib/block_scout_web/templates/transaction/overview.html.eex:114
+#: lib/block_scout_web/templates/transaction/overview.html.eex:200
msgid "Used"
msgstr ""
@@ -1039,7 +1041,7 @@ msgid "Validations"
msgstr ""
#, elixir-format
-#: lib/block_scout_web/templates/transaction/overview.html.eex:96
+#: lib/block_scout_web/templates/transaction/overview.html.eex:182
msgid "Value"
msgstr ""
@@ -1216,3 +1218,20 @@ msgstr ""
#: lib/block_scout_web/templates/api_docs/index.html.eex:7
msgid "This API is provided for developers transitioning their applications from Etherscan to BlockScout. It supports GET and POST requests."
msgstr ""
+
+#, elixir-format
+#: lib/block_scout_web/templates/transaction/overview.html.eex:153
+msgid "Raw Input"
+msgstr ""
+
+#, elixir-format
+#: lib/block_scout_web/templates/transaction/overview.html.eex:156
+msgid "Show Raw Input"
+msgstr ""
+
+#, elixir-format
+#: lib/block_scout_web/templates/transaction/overview.html.eex:130
+#: lib/block_scout_web/templates/transaction/overview.html.eex:140
+#: lib/block_scout_web/templates/transaction/overview.html.eex:164
+msgid "copy"
+msgstr ""
diff --git a/apps/ethereum_jsonrpc/mix.exs b/apps/ethereum_jsonrpc/mix.exs
index 0ec61acd69..e2f8458821 100644
--- a/apps/ethereum_jsonrpc/mix.exs
+++ b/apps/ethereum_jsonrpc/mix.exs
@@ -79,7 +79,7 @@ defmodule EthereumJsonrpc.MixProject do
# Convert unix timestamps in JSONRPC to DateTimes
{:timex, "~> 3.4"},
# Encode/decode function names and arguments
- {:ex_abi, "~> 0.1.16"},
+ {:ex_abi, "~> 0.1.17"},
# `:verify_fun` for `Socket.Web.connect`
{:ssl_verify_fun, "~> 1.1"},
# `EthereumJSONRPC.WebSocket`
diff --git a/apps/explorer/lib/explorer/chain/transaction.ex b/apps/explorer/lib/explorer/chain/transaction.ex
index fecf72722c..40a14b103e 100644
--- a/apps/explorer/lib/explorer/chain/transaction.ex
+++ b/apps/explorer/lib/explorer/chain/transaction.ex
@@ -3,8 +3,12 @@ defmodule Explorer.Chain.Transaction do
use Explorer.Schema
+ require Logger
+
import Ecto.Query, only: [dynamic: 2, from: 2, preload: 3, subquery: 1, where: 3]
+ alias ABI.FunctionSelector
+
alias Ecto.Changeset
alias Explorer.Chain.{
@@ -415,6 +419,54 @@ defmodule Explorer.Chain.Transaction do
preload(query, [tt], token_transfers: ^token_transfers_query)
end
+ # Because there is no contract association, we know the contract was not verified
+ def decoded_input_data(%__MODULE__{to_address: nil}), do: {:error, :no_to_address}
+ def decoded_input_data(%__MODULE__{input: %{bytes: bytes}}) when bytes in [nil, <<>>], do: {:error, :no_input_data}
+ def decoded_input_data(%__MODULE__{to_address: %{contract_code: nil}}), do: {:error, :not_a_contract_call}
+ def decoded_input_data(%__MODULE__{to_address: %{smart_contract: nil}}), do: {:error, :contract_not_verified}
+
+ def decoded_input_data(%__MODULE__{input: %{bytes: data}, to_address: %{smart_contract: %{abi: abi}}, hash: hash}) do
+ with {:ok, {selector, values}} <- find_and_decode(abi, data, hash),
+ {:ok, mapping} <- selector_mapping(selector, values, hash),
+ identifier <- Base.encode16(selector.method_id, case: :lower),
+ text <- function_call(selector.function, mapping),
+ do: {:ok, identifier, text, mapping}
+ end
+
+ defp function_call(name, mapping) do
+ text =
+ mapping
+ |> Stream.map(fn {name, type, _} -> [type, " ", name] end)
+ |> Enum.intersperse(", ")
+
+ IO.iodata_to_binary([name, "(", text, ")"])
+ end
+
+ defp find_and_decode(abi, data, hash) do
+ result =
+ abi
+ |> ABI.parse_specification()
+ |> ABI.find_and_decode(data)
+
+ {:ok, result}
+ rescue
+ _ ->
+ Logger.warn(fn -> ["Could not decode input data for transaction: ", Hash.to_iodata(hash)] end)
+ {:error, :could_not_decode}
+ end
+
+ defp selector_mapping(selector, values, hash) do
+ types = Enum.map(selector.types, &FunctionSelector.encode_type/1)
+
+ mapping = Enum.zip([selector.input_names, types, values])
+
+ {:ok, mapping}
+ rescue
+ _ ->
+ Logger.warn(fn -> ["Could not decode input data for transaction: ", Hash.to_iodata(hash)] end)
+ {:error, :could_not_decode}
+ end
+
@doc """
Adds to the given transaction's query a `where` with one of the conditions that the matched
function returns.
diff --git a/apps/explorer/test/explorer/chain/transaction_test.exs b/apps/explorer/test/explorer/chain/transaction_test.exs
index 7855daa2a8..df82de13ff 100644
--- a/apps/explorer/test/explorer/chain/transaction_test.exs
+++ b/apps/explorer/test/explorer/chain/transaction_test.exs
@@ -213,4 +213,30 @@ defmodule Explorer.Chain.TransactionTest do
assert last_nonce == nil
end
end
+
+ describe "decoded_input_data/1" do
+ test "that a tranasction that is not a contract call returns a commensurate error" do
+ transaction = insert(:transaction)
+
+ assert Transaction.decoded_input_data(transaction) == {:error, :not_a_contract_call}
+ end
+
+ test "that a contract call transaction that has no verified contract returns a commensurate error" do
+ transaction =
+ :transaction
+ |> insert(to_address: insert(:contract_address))
+ |> Repo.preload(to_address: :smart_contract)
+
+ assert Transaction.decoded_input_data(transaction) == {:error, :contract_not_verified}
+ end
+
+ test "that a contract call transaction that has a verified contract returns the decoded input data" do
+ transaction =
+ :transaction_to_verified_contract
+ |> insert()
+ |> Repo.preload(to_address: :smart_contract)
+
+ assert Transaction.decoded_input_data(transaction) == {:ok, "60fe47b1", "set(uint256 x)", [{"x", "uint256", 50}]}
+ end
+ end
end
diff --git a/apps/explorer/test/support/factory.ex b/apps/explorer/test/support/factory.ex
index 54f99731a8..bb0c7e702f 100644
--- a/apps/explorer/test/support/factory.ex
+++ b/apps/explorer/test/support/factory.ex
@@ -92,6 +92,26 @@ defmodule Explorer.Factory do
}
}
""",
+ abi: [
+ %{
+ "constant" => false,
+ "inputs" => [%{"name" => "x", "type" => "uint256"}],
+ "name" => "set",
+ "outputs" => [],
+ "payable" => false,
+ "stateMutability" => "nonpayable",
+ "type" => "function"
+ },
+ %{
+ "constant" => true,
+ "inputs" => [],
+ "name" => "get",
+ "outputs" => [%{"name" => "", "type" => "uint256"}],
+ "payable" => false,
+ "stateMutability" => "view",
+ "type" => "function"
+ }
+ ],
version: "v0.4.24+commit.e67f0147",
optimized: false
}
@@ -419,6 +439,23 @@ defmodule Explorer.Factory do
}
end
+ def transaction_to_verified_contract_factory do
+ smart_contract = build(:smart_contract)
+
+ address = %Address{
+ hash: address_hash(),
+ contract_code: contract_code_info().bytecode,
+ smart_contract: smart_contract
+ }
+
+ input_data =
+ "set(uint)"
+ |> ABI.encode([50])
+ |> Base.encode16(case: :lower)
+
+ build(:transaction, to_address: address, input: "0x" <> input_data)
+ end
+
def transaction_hash do
{:ok, transaction_hash} =
"transaction_hash"
@@ -441,33 +478,15 @@ defmodule Explorer.Factory do
end
def smart_contract_factory() do
+ contract_code_info = contract_code_info()
+
%SmartContract{
address_hash: insert(:address).hash,
- compiler_version: "0.4.24",
- name: "SimpleStorage",
- contract_source_code:
- "pragma solidity ^0.4.24; contract SimpleStorage {uint storedData; function set(uint x) public {storedData = x; } function get() public constant returns (uint) {return storedData; } }",
- optimization: false,
- abi: [
- %{
- "constant" => false,
- "inputs" => [%{"name" => "x", "type" => "uint256"}],
- "name" => "set",
- "outputs" => [],
- "payable" => false,
- "stateMutability" => "nonpayable",
- "type" => "function"
- },
- %{
- "constant" => true,
- "inputs" => [],
- "name" => "get",
- "outputs" => [%{"name" => "", "type" => "uint256"}],
- "payable" => false,
- "stateMutability" => "view",
- "type" => "function"
- }
- ]
+ compiler_version: contract_code_info.version,
+ name: contract_code_info.name,
+ contract_source_code: contract_code_info.source_code,
+ optimization: contract_code_info.optimized,
+ abi: contract_code_info.abi
}
end
diff --git a/mix.lock b/mix.lock
index 67b8ac8a69..eb2d1cd627 100644
--- a/mix.lock
+++ b/mix.lock
@@ -27,7 +27,7 @@
"earmark": {:hex, :earmark, "1.2.6", "b6da42b3831458d3ecc57314dff3051b080b9b2be88c2e5aa41cd642a5b044ed", [:mix], [], "hexpm"},
"ecto": {:hex, :ecto, "2.2.11", "4bb8f11718b72ba97a2696f65d247a379e739a0ecabf6a13ad1face79844791c", [:mix], [{:db_connection, "~> 1.1", [hex: :db_connection, repo: "hexpm", optional: true]}, {:decimal, "~> 1.2", [hex: :decimal, repo: "hexpm", optional: false]}, {:mariaex, "~> 0.8.0", [hex: :mariaex, repo: "hexpm", optional: true]}, {:poison, "~> 2.2 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: true]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.13.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, repo: "hexpm", optional: true]}], "hexpm"},
"elixir_make": {:hex, :elixir_make, "0.4.2", "332c649d08c18bc1ecc73b1befc68c647136de4f340b548844efc796405743bf", [:mix], [], "hexpm"},
- "ex_abi": {:hex, :ex_abi, "0.1.16", "3bb346968995f505b0f2fed1704321c572349e29614f5a2dbe2ae8fc0f18a89e", [:mix], [{:exth_crypto, "~> 0.1.4", [hex: :exth_crypto, repo: "hexpm", optional: false]}], "hexpm"},
+ "ex_abi": {:hex, :ex_abi, "0.1.17", "11822f88b3ed70773c64858a49321b3c51ed913128a3f9fc7a05fa7ceb19d8fa", [:mix], [{:exth_crypto, "~> 0.1.4", [hex: :exth_crypto, repo: "hexpm", optional: false]}], "hexpm"},
"ex_cldr": {:hex, :ex_cldr, "1.3.2", "8f4a00c99d1c537b8e8db7e7903f4bd78d82a7289502d080f70365392b13921b", [:mix], [{:abnf2, "~> 0.1", [hex: :abnf2, optional: false]}, {:decimal, "~> 1.4", [hex: :decimal, optional: false]}, {:gettext, "~> 0.13", [hex: :gettext, optional: true]}, {:poison, "~> 2.1 or ~> 3.0", [hex: :poison, optional: true]}]},
"ex_cldr_numbers": {:hex, :ex_cldr_numbers, "1.2.0", "ef27299922da913ffad1ed296cacf28b6452fc1243b77301dc17c03276c6ee34", [:mix], [{:decimal, "~> 1.4", [hex: :decimal, optional: false]}, {:ex_cldr, "~> 1.3", [hex: :ex_cldr, optional: false]}, {:poison, "~> 2.1 or ~> 3.1", [hex: :poison, optional: false]}]},
"ex_cldr_units": {:hex, :ex_cldr_units, "1.1.1", "b3c7256709bdeb3740a5f64ce2bce659eb9cf4cc1afb4cf94aba033b4a18bc5f", [:mix], [{:ex_cldr, "~> 1.0", [hex: :ex_cldr, optional: false]}, {:ex_cldr_numbers, "~> 1.0", [hex: :ex_cldr_numbers, optional: false]}]},
@@ -37,7 +37,7 @@
"exactor": {:hex, :exactor, "2.2.4", "5efb4ddeb2c48d9a1d7c9b465a6fffdd82300eb9618ece5d34c3334d5d7245b1", [:mix], []},
"excoveralls": {:git, "https://github.com/KronicDeth/excoveralls.git", "0a859b68851eeba9b43eba59fbc8f9098299cfe1", [branch: "circle-workflows"]},
"exjsx": {:hex, :exjsx, "4.0.0", "60548841e0212df401e38e63c0078ec57b33e7ea49b032c796ccad8cde794b5c", [:mix], [{:jsx, "~> 2.8.0", [hex: :jsx, optional: false]}]},
- "exth_crypto": {:hex, :exth_crypto, "0.1.4", "11f9084dfd70d4f9e96f2710a472f4e6b23044b97530c719550c2b0450ffeb61", [:mix], [{:binary, "~> 0.0.4", [hex: :binary, optional: false]}, {:keccakf1600, "~> 2.0.0", [hex: :keccakf1600_orig, optional: false]}, {:libsecp256k1, "~> 0.1.3", [hex: :libsecp256k1, optional: false]}]},
+ "exth_crypto": {:hex, :exth_crypto, "0.1.6", "8e636a9bcb75d8e32451be96e547a495121ed2178d078db294edb0f81f7cf2e8", [:mix], [{:binary, "~> 0.0.4", [hex: :binary, repo: "hexpm", optional: false]}, {:keccakf1600, "~> 2.0.0", [hex: :keccakf1600_orig, repo: "hexpm", optional: false]}, {:libsecp256k1, "~> 0.1.9", [hex: :libsecp256k1, repo: "hexpm", optional: false]}], "hexpm"},
"exvcr": {:hex, :exvcr, "0.10.3", "1ae3b97560430acfa88ebc737c85b2b7a9dbacd8a2b26789a19718b51ae3522c", [:mix], [{:exactor, "~> 2.2", [hex: :exactor, repo: "hexpm", optional: false]}, {:exjsx, "~> 4.0", [hex: :exjsx, repo: "hexpm", optional: false]}, {:httpoison, "~> 1.0", [hex: :httpoison, repo: "hexpm", optional: true]}, {:httpotion, "~> 3.1", [hex: :httpotion, repo: "hexpm", optional: true]}, {:ibrowse, "~> 4.4", [hex: :ibrowse, repo: "hexpm", optional: true]}, {:meck, "~> 0.8", [hex: :meck, repo: "hexpm", optional: false]}], "hexpm"},
"file_system": {:hex, :file_system, "0.2.6", "fd4dc3af89b9ab1dc8ccbcc214a0e60c41f34be251d9307920748a14bf41f1d3", [:mix], [], "hexpm"},
"floki": {:hex, :floki, "0.20.4", "be42ac911fece24b4c72f3b5846774b6e61b83fe685c2fc9d62093277fb3bc86", [:mix], [{:html_entities, "~> 0.4.0", [hex: :html_entities, repo: "hexpm", optional: false]}, {:mochiweb, "~> 2.15", [hex: :mochiweb, repo: "hexpm", optional: false]}], "hexpm"},