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