feat: decode transaction input on overview

pull/1059/head
zachdaniel 6 years ago committed by Luke Imhoff
parent b5844f413b
commit dd5dec4da2
  1. 1
      apps/block_scout_web/assets/css/app.scss
  2. 9
      apps/block_scout_web/assets/css/components/_transaction-input.scss
  3. 1
      apps/block_scout_web/assets/js/app.js
  4. 3
      apps/block_scout_web/assets/js/lib/clipboard_buttons.js
  5. 21
      apps/block_scout_web/assets/js/lib/swappable_item.js
  6. 1
      apps/block_scout_web/lib/block_scout_web/controllers/transaction_internal_transaction_controller.ex
  7. 1
      apps/block_scout_web/lib/block_scout_web/controllers/transaction_log_controller.ex
  8. 100
      apps/block_scout_web/lib/block_scout_web/templates/transaction/overview.html.eex
  9. 4
      apps/block_scout_web/lib/block_scout_web/views/transaction_view.ex
  10. 47
      apps/block_scout_web/priv/gettext/default.pot
  11. 47
      apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po
  12. 2
      apps/ethereum_jsonrpc/mix.exs
  13. 52
      apps/explorer/lib/explorer/chain/transaction.ex
  14. 26
      apps/explorer/test/explorer/chain/transaction_test.exs
  15. 69
      apps/explorer/test/support/factory.ex
  16. 4
      mix.lock

@ -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;

@ -0,0 +1,9 @@
.raw-transaction-input{
display: none;
}
.transaction-input-text{
resize: vertical;
overflow: auto;
word-break: break-all;
}

@ -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'

@ -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)

@ -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)
})

@ -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

@ -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

@ -76,14 +76,100 @@
<!-- Input -->
<dl class="row mb-0">
<dt class="col-sm-3 text-muted"> <%= gettext "Input" %> </dt>
<dd class="col-sm-9">
<div class="tile tile-muted">
<pre class="pre-scrollable pre-scrollable-shorty pre-wrap mb-0">
<code><%= @transaction.input %></code>
</pre>
<%= case decoded_input_data(@transaction) do %>
<% {:error, :contract_not_verified} -> %>
<dt class="col-sm-3 text-muted"> <%= gettext "Input" %> </dt>
<dd class="col-sm-9">
<div class="alert alert-danger">
To see decoded input data, the <a href="<%= address_verify_contract_path(@conn, :new, @transaction.to_address.hash)%>">contract must be verified.</a>
</div>
</dd>
<% {:error, :could_not_decode} -> %>
<dt class="col-sm-3 text-muted"> <%= gettext "Input" %> </dt>
<dd class="col-sm-9">
<div class="alert alert-danger">
Failed to decode input data. Some dynamic types are not currently supported.
</div>
</dd>
<% {:ok, method_id, text, mapping} -> %>
<dt class="col-sm-3 text-muted"> <%= gettext "Input" %> </dt>
<dd class="col-sm-9">
<table summary="Transaction Info" class="table thead-light table-bordered">
<tr>
<td>Method Id</td>
<td colspan="3"><code>0x<%= method_id %></code></td>
</tr>
<tr>
<td>Call</td>
<td colspan="3"><code><%= text %></code></td>
</tr>
</table>
<table summary="Transaction Inputs" class="table thead-light table-bordered table-responsive">
<tr>
<th scope="col">#</th>
<th scope="col">Name</th>
<th scope="col">Type</th>
<th scope="col">Data</th>
<th scope="col"></th>
<tr>
<%= for {{name, type, value}, index} <- Enum.with_index(mapping) do %>
<tr>
<th scope="row"><%= index %></th>
<td><%= name %></td>
<td><%= type %></td>
<%= case type do %>
<% "address" -> %>
<% address = "0x" <> Base.encode16(value, case: :lower) %>
<td>
<div class="transaction-input-text">
<a href="<%= address_path(@conn, :show, address) %>" target="_blank"> <%= address %> </a>
</div>
</td>
<td>
<button type="button" class="copy" id="button" data-toggle="tooltip" data-placement="top" data-clipboard-text="<%= address %>" aria-label="Copy Value">
<%= gettext "copy"%>
</button>
</td>
<% _ -> %>
<td>
<div class="transaction-input-text"><%= value %></textarea>
</td>
<td>
<button type="button" class="copy" id="button" data-toggle="tooltip" data-placement="top" data-clipboard-text="<%= value %>" aria-label="Copy Value">
<%= gettext "copy"%>
</button>
</td>
<% end %>
</tr>
<% end %>
</table>
</dd>
<% _ -> %>
<%= nil %>
<% end %>
<%= unless @transaction.input.bytes in [<<>>, nil] do %>
<dt class="col-sm-3 text-muted"><%= gettext "Raw Input" %></dt>
<dd class="col-sm-9">
<div swappable-item>
<button swapper class="button button-primary"><%= gettext "Show Raw Input"%></button>
</div>
</dd>
<div swappable-item class="raw-transaction-input">
<button swapper type="button" class="close pr-2" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
<div class="tile tile-muted">
<button type="button" class="copy" id="button" data-toggle="tooltip" data-placement="top" data-clipboard-text="<%= @transaction.input %>" aria-label="Copy Value">
<%= gettext "copy"%>
</button>
<pre class="pre-scrollable pre-scrollable-shorty pre-wrap mb-0">
<code><%= @transaction.input %></code>
</pre>
</div>
</div>
</dd>
<% end %>
</dl>
</div>
</div>

@ -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.
"""

@ -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 ""

@ -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 ""

@ -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`

@ -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.

@ -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

@ -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

@ -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"},

Loading…
Cancel
Save