parent
1e449cca99
commit
b3d6964650
@ -0,0 +1,46 @@ |
||||
defmodule Explorer.SmartContract.Solidity.CompilerVersion do |
||||
@moduledoc """ |
||||
Adapter for fetching compiler versions from https://solc-bin.ethereum.org/bin/list.json. |
||||
""" |
||||
|
||||
alias HTTPoison.{Error, Response} |
||||
|
||||
@doc """ |
||||
Fetches list of compilers from Ethereum Solidity API. |
||||
""" |
||||
def fetch_versions() do |
||||
headers = [{"Content-Type", "application/json"}] |
||||
|
||||
case HTTPoison.get(source_url(), headers) do |
||||
{:ok, %Response{body: body, status_code: 200}} -> |
||||
{:ok, format_data(body)} |
||||
|
||||
{:ok, %Response{body: body, status_code: status_code}} when status_code in 400..499 -> |
||||
{:error, decode_json(body)["error"]} |
||||
|
||||
{:error, %Error{reason: reason}} -> |
||||
{:error, reason} |
||||
end |
||||
end |
||||
|
||||
defp format_data(json) do |
||||
{:ok, releases} = |
||||
Jason.decode!(json) |
||||
|> Map.fetch("releases") |
||||
|
||||
Map.to_list(releases) |
||||
|> Enum.map(fn {key, _value} -> {key, key} end) |
||||
|> Enum.sort() |
||||
|> Enum.reverse() |
||||
end |
||||
|
||||
defp decode_json(json) do |
||||
Jason.decode!(json) |
||||
end |
||||
|
||||
defp source_url do |
||||
solc_bin_api_url = Application.get_env(:explorer, :solc_bin_api_url) |
||||
|
||||
"#{solc_bin_api_url}/bin/list.json" |
||||
end |
||||
end |
@ -0,0 +1,34 @@ |
||||
defmodule Explorer.SmartContract.Solidity.CompilerVersionTest do |
||||
use ExUnit.Case |
||||
|
||||
doctest Explorer.SmartContract.Solidity.CompilerVersion |
||||
|
||||
alias Explorer.SmartContract.Solidity.CompilerVersion |
||||
alias Plug.Conn |
||||
|
||||
describe "fetch_versions" do |
||||
setup do |
||||
bypass = Bypass.open() |
||||
|
||||
Application.put_env(:explorer, :solc_bin_api_url, "http://localhost:#{bypass.port}") |
||||
|
||||
{:ok, bypass: bypass} |
||||
end |
||||
|
||||
test "fetches the list of the solidity compiler versions", %{ bypass: bypass } do |
||||
Bypass.expect(bypass, fn conn -> |
||||
assert "GET" == conn.method |
||||
assert "/bin/list.json" == conn.request_path |
||||
|
||||
Conn.resp(conn, 200, solc_bin_versions()) |
||||
end) |
||||
|
||||
assert {:ok, versions} = CompilerVersion.fetch_versions() |
||||
assert Enum.any?(versions, fn (item) -> item == {"0.4.9", "0.4.9"} end) == true |
||||
end |
||||
end |
||||
|
||||
def solc_bin_versions() do |
||||
File.read!("./test/support/fixture/smart_contract/solc_bin.json") |
||||
end |
||||
end |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,14 @@ |
||||
@import "section"; |
||||
@import "dot"; |
||||
|
||||
@import "address"; |
||||
@import "block"; |
||||
@import "blocks"; |
||||
@import "chain"; |
||||
@import "footer"; |
||||
@import "header"; |
||||
@import "internal_transaction"; |
||||
@import "pagination"; |
||||
@import "transaction"; |
||||
@import "transaction_log"; |
||||
@import "transactions"; |
@ -0,0 +1,23 @@ |
||||
defmodule ExplorerWeb.AddressVerifyContractController do |
||||
use ExplorerWeb, :controller |
||||
|
||||
alias Explorer.Chain |
||||
alias Explorer.SmartContract.Solidity.CompilerVersion |
||||
|
||||
def new(conn, %{"address_id" => address_hash_string}) do |
||||
{:ok, hash} = Chain.string_to_address_hash(address_hash_string) |
||||
{:ok, address} = Chain.hash_to_address(hash) |
||||
|
||||
changeset = Chain.Address.changeset(%Chain.Address{}, %{}) |
||||
|
||||
{:ok, compiler_versions} = CompilerVersion.fetch_versions() |
||||
|
||||
render(conn, "new.html", |
||||
address: address, |
||||
changeset: changeset, |
||||
compiler_versions: compiler_versions) |
||||
end |
||||
|
||||
def create(_conn, _params) do |
||||
end |
||||
end |
@ -0,0 +1,47 @@ |
||||
<section class="container__section block"> |
||||
<div class="address__container"> |
||||
<div class="address__tabs"> |
||||
<h2 class="address__tab address__tab--active"> |
||||
<%= link( |
||||
gettext("Contract Source Code"), |
||||
class: "address__link address__link--active", |
||||
to: '#' |
||||
) %> |
||||
</h2> |
||||
</div> |
||||
<div class="contract__container"> |
||||
<%= form_for @changeset, |
||||
address_verify_contract_path(@conn, :create, @conn.assigns.locale, @conn.params["address_id"]), |
||||
fn f -> %> |
||||
|
||||
<div class="form-group"> |
||||
<label>Contract Address</label> |
||||
<%= text_input f, :address, class: "form-control" %> |
||||
</div> |
||||
|
||||
<div class="form-group"> |
||||
<label>Contract Name:</label> |
||||
<%= text_input f, :name, class: "form-control" %> |
||||
</div> |
||||
|
||||
<div class="form-group"> |
||||
<label>Compiler:</label> |
||||
<%= select f, :compiler, @compiler_versions, class: "form-control" %> |
||||
</div> |
||||
|
||||
<div class="form-group"> |
||||
<label>Optimization:</label> |
||||
<%= select f, :optimization, ["yes", "no"], class: "form-control" %> |
||||
</div> |
||||
|
||||
<div class="form-group"> |
||||
<label>Enter the Solidity Contract Code below</label> |
||||
<%= textarea f, :code, class: "form-control", rows: 3 %> |
||||
</div> |
||||
|
||||
<%= submit "Verify and publish", class: "button--primary" %> |
||||
<%= reset "Reset", class: "button--tertiary" %> |
||||
<% end %> |
||||
</div> |
||||
</div> |
||||
</section> |
@ -0,0 +1,3 @@ |
||||
defmodule ExplorerWeb.AddressVerifyContractView do |
||||
use ExplorerWeb, :view |
||||
end |
Loading…
Reference in new issue