Merge branch 'master' into ab-show-all-token-transfers

pull/2190/head
Ayrat Badykov 6 years ago committed by GitHub
commit fb6b9df3ab
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 7
      CHANGELOG.md
  2. 31
      apps/block_scout_web/assets/css/components/_navbar.scss
  3. 1
      apps/block_scout_web/assets/js/app.js
  4. 9
      apps/block_scout_web/assets/js/pages/layout.js
  5. 2
      apps/block_scout_web/config/config.exs
  6. 4
      apps/block_scout_web/lib/block_scout_web/templates/address/_responsive_hash.html.eex
  7. 2
      apps/block_scout_web/lib/block_scout_web/templates/api_docs/eth_rpc.html.eex
  8. 2
      apps/block_scout_web/lib/block_scout_web/templates/api_docs/index.html.eex
  9. 4
      apps/block_scout_web/lib/block_scout_web/templates/layout/_topnav.html.eex
  10. 10
      apps/block_scout_web/lib/block_scout_web/views/api_docs_view.ex
  11. 10
      apps/explorer/lib/explorer/smart_contract/solidity/code_compiler.ex
  12. 7
      apps/explorer/lib/explorer/smart_contract/verifier.ex
  13. 8
      apps/explorer/lib/explorer/smart_contract/verifier/constructor_arguments.ex
  14. 1
      apps/explorer/mix.exs
  15. 5
      apps/explorer/priv/compile_solc.js
  16. 14
      apps/explorer/test/explorer/smart_contract/solidity/code_compiler_test.exs
  17. 32
      apps/explorer/test/explorer/smart_contract/verifier_test.exs
  18. 3874
      apps/explorer/test/support/fixture/smart_contract/large_smart_contract.sol
  19. 76
      apps/explorer/test/support/fixture/smart_contract/solidity_0.5.9_smart_contract.sol
  20. 1
      mix.lock

@ -7,8 +7,11 @@
- [#2191](https://github.com/poanetwork/blockscout/pull/2191) - allow to configure token metadata update interval - [#2191](https://github.com/poanetwork/blockscout/pull/2191) - allow to configure token metadata update interval
- [#2146](https://github.com/poanetwork/blockscout/pull/2146) - feat: add eth_getLogs rpc endpoint - [#2146](https://github.com/poanetwork/blockscout/pull/2146) - feat: add eth_getLogs rpc endpoint
- [#2190](https://github.com/poanetwork/blockscout/pull/2190) - show all token transfers - [#2190](https://github.com/poanetwork/blockscout/pull/2190) - show all token transfers
- [#2193](https://github.com/poanetwork/blockscout/pull/2193) - feat: add BLOCKSCOUT_HOST, and use it in API docs
### Fixes ### Fixes
- [#2254](https://github.com/poanetwork/blockscout/pull/2254) - search length issue, tile link wrapping issue
- [#2238](https://github.com/poanetwork/blockscout/pull/2238) - header content alignment issue, hide navbar on outside click
- [#2229](https://github.com/poanetwork/blockscout/pull/2229) - gap issue between qr and copy button in token transfers, top cards width and height issue - [#2229](https://github.com/poanetwork/blockscout/pull/2229) - gap issue between qr and copy button in token transfers, top cards width and height issue
- [#2201](https://github.com/poanetwork/blockscout/pull/2201) - footer columns fix - [#2201](https://github.com/poanetwork/blockscout/pull/2201) - footer columns fix
- [#2179](https://github.com/poanetwork/blockscout/pull/2179) - fix docker build error - [#2179](https://github.com/poanetwork/blockscout/pull/2179) - fix docker build error
@ -45,7 +48,9 @@
- [#2173](https://github.com/poanetwork/blockscout/pull/2173) - handle correctly empty transactions - [#2173](https://github.com/poanetwork/blockscout/pull/2173) - handle correctly empty transactions
- [#2174](https://github.com/poanetwork/blockscout/pull/2174) - fix reward channel joining - [#2174](https://github.com/poanetwork/blockscout/pull/2174) - fix reward channel joining
- [#2186](https://github.com/poanetwork/blockscout/pull/2186) - fix net version test - [#2186](https://github.com/poanetwork/blockscout/pull/2186) - fix net version test
- [#2167](https://github.com/poanetwork/blockscout/pull/2168) - feat: document eth rpc api mimicking endpoints - [#2167](https://github.com/poanetwork/blockscout/pull/2167) - feat: document eth rpc api mimicking endpoints
- [#2225](https://github.com/poanetwork/blockscout/pull/2225) - fix metadata decoding in Solidity 0.5.9 smart contract verification
- [#2204](https://github.com/poanetwork/blockscout/pull/2204) - fix large contract verification
### Chore ### Chore
- [#2127](https://github.com/poanetwork/blockscout/pull/2127) - use previouse chromedriver version - [#2127](https://github.com/poanetwork/blockscout/pull/2127) - use previouse chromedriver version

@ -21,8 +21,8 @@ $navbar-logo-width: auto !default;
.nav-item { .nav-item {
font-size: 14px; font-size: 14px;
} }
.navbar-nav { .navbar-nav {
flex-grow: 1;
.nav-link { .nav-link {
align-items: center; align-items: center;
@ -151,7 +151,13 @@ $navbar-logo-width: auto !default;
} }
@include media-breakpoint-up(xl) { @include media-breakpoint-up(xl) {
width: 280px; width: 340px;
}
@media (min-width: 1366px) {
width: 500px;
}
@media (min-width: 1440px) {
width: 580px;
} }
} }
.input-group-append { .input-group-append {
@ -198,7 +204,7 @@ $navbar-logo-width: auto !default;
width: 100%; width: 100%;
.awesomplete { .awesomplete {
@include media-breakpoint-down(sm) { @include media-breakpoint-down(lg) {
width: 100%; width: 100%;
} }
} }
@ -210,6 +216,10 @@ $navbar-logo-width: auto !default;
.navbar-brand { .navbar-brand {
margin-left: 0; margin-left: 0;
flex-shrink: 1;
.navbar-logo {
max-width: 100%;
}
} }
.navbar-logo { .navbar-logo {
@ -227,3 +237,18 @@ $navbar-logo-width: auto !default;
.add-border { .add-border {
border: 1px solid transparentize($white, 0.30); border: 1px solid transparentize($white, 0.30);
} }
.navbar-collapse {
justify-content: flex-end;
align-items: flex-start;
flex-shrink: 0;
@media (min-width: 992px) {
align-items: center;
}
}
.navbar-container, .navbar-primary {
@include media-breakpoint-up(xl) {
padding-right: 0;
}
}

@ -31,6 +31,7 @@ import './pages/chain'
import './pages/pending_transactions' import './pages/pending_transactions'
import './pages/transaction' import './pages/transaction'
import './pages/transactions' import './pages/transactions'
import './pages/layout'
import './pages/admin/tasks.js' import './pages/admin/tasks.js'

@ -0,0 +1,9 @@
import $ from 'jquery'
$(document).click(function (event) {
var clickover = $(event.target)
var _opened = $('.navbar-collapse').hasClass('show')
if (_opened === true && $('.navbar').find(clickover).length < 1) {
$('.navbar-toggler').click()
}
})

@ -41,7 +41,7 @@ config :block_scout_web, BlockScoutWeb.Endpoint,
] ]
], ],
url: [ url: [
host: "localhost", host: System.get_env("BLOCKSCOUT_HOST") || "localhost",
path: System.get_env("NETWORK_PATH") || "/" path: System.get_env("NETWORK_PATH") || "/"
], ],
render_errors: [view: BlockScoutWeb.ErrorView, accepts: ~w(html json)], render_errors: [view: BlockScoutWeb.ErrorView, accepts: ~w(html json)],

@ -5,8 +5,8 @@
<%= if assigns[:truncate] do %> <%= if assigns[:truncate] do %>
<%= BlockScoutWeb.AddressView.trimmed_hash(@address.hash) %> <%= BlockScoutWeb.AddressView.trimmed_hash(@address.hash) %>
<% else %> <% else %>
<span class="d-none d-md-none d-lg-inline"><%= @address %></span> <span class="d-none d-md-none d-xl-inline"><%= @address %></span>
<span class="d-md-inline-block d-lg-none"><%= BlockScoutWeb.AddressView.trimmed_hash(@address.hash) %></span> <span class="d-md-inline-block d-xl-none"><%= BlockScoutWeb.AddressView.trimmed_hash(@address.hash) %></span>
<% end %> <% end %>
<% end %> <% end %>
</span> </span>

@ -2,7 +2,7 @@
<div class="card"> <div class="card">
<div class="card-body"> <div class="card-body">
<h1 class="card-title margin-bottom-sm"><%= gettext("ETH RPC API Documentation") %></h2> <h1 class="card-title margin-bottom-sm"><%= gettext("ETH RPC API Documentation") %></h2>
<p class="api-text-monospace" data-endpoint-url="<%= BlockScoutWeb.Endpoint.url() %>/api/eth_rpc">[ <%= gettext "Base URL:" %> <%= @conn.host %>/api/eth_rpc ]</p> <p class="api-text-monospace" data-endpoint-url="<%= BlockScoutWeb.Endpoint.url() %>/api/eth_rpc">[ <%= gettext "Base URL:" %> <%= url() %>/api/eth_rpc ]</p>
<p class="card-subtitle margin-bottom-0"> <p class="card-subtitle margin-bottom-0">
<%= gettext "This API is provided to support some rpc methods in the exact format specified for ethereum nodes, which can be found " %> <%= gettext "This API is provided to support some rpc methods in the exact format specified for ethereum nodes, which can be found " %>

@ -2,7 +2,7 @@
<div class="card"> <div class="card">
<div class="card-body"> <div class="card-body">
<h1 class="card-title margin-bottom-sm"><%= gettext("API Documentation") %></h2> <h1 class="card-title margin-bottom-sm"><%= gettext("API Documentation") %></h2>
<p class="api-text-monospace" data-endpoint-url="<%= BlockScoutWeb.Endpoint.url() %>/api">[ <%= gettext "Base URL:" %> <%= @conn.host %>/api ]</p> <p class="api-text-monospace" data-endpoint-url="<%= BlockScoutWeb.Endpoint.url() %>/api">[ <%= gettext "Base URL:" %> <%= url() %>/api ]</p>
<p class="card-subtitle margin-bottom-0"><%= gettext "This API is provided for developers transitioning their applications from Etherscan to BlockScout. It supports GET and POST requests." %></p> <p class="card-subtitle margin-bottom-0"><%= gettext "This API is provided for developers transitioning their applications from Etherscan to BlockScout. It supports GET and POST requests." %></p>
</div> </div>
<div class="api-anchors-list"> <div class="api-anchors-list">

@ -1,5 +1,5 @@
<nav class="navbar navbar-dark navbar-expand-lg navbar-primary" data-selector="navbar"> <nav class="navbar navbar-dark navbar-expand-lg navbar-primary" data-selector="navbar">
<div class="container"> <div class="container-fluid navbar-container">
<%= link to: chain_path(@conn, :show), class: "navbar-brand", "data-test": "header_logo" do %> <%= link to: chain_path(@conn, :show), class: "navbar-brand", "data-test": "header_logo" do %>
<img class="navbar-logo" src="<%= logo() %>" alt="<%= subnetwork_title() %>" /> <img class="navbar-logo" src="<%= logo() %>" alt="<%= subnetwork_title() %>" />
<% end %> <% end %>
@ -7,7 +7,7 @@
<span class="navbar-toggler-icon"></span> <span class="navbar-toggler-icon"></span>
</button> </button>
<div class="collapse navbar-collapse" id="navbarSupportedContent"> <div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto"> <ul class="navbar-nav">
<li class="nav-item dropdown"> <li class="nav-item dropdown">
<a class="nav-link topnav-nav-link dropdown-toggle" href="#" id="navbarBlocksDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> <a class="nav-link topnav-nav-link dropdown-toggle" href="#" id="navbarBlocksDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<span class="nav-link-icon"> <span class="nav-link-icon">

@ -1,7 +1,7 @@
defmodule BlockScoutWeb.APIDocsView do defmodule BlockScoutWeb.APIDocsView do
use BlockScoutWeb, :view use BlockScoutWeb, :view
alias BlockScoutWeb.LayoutView alias BlockScoutWeb.{Endpoint, LayoutView}
def action_tile_id(module, action) do def action_tile_id(module, action) do
"#{module}-#{action}" "#{module}-#{action}"
@ -33,4 +33,12 @@ defmodule BlockScoutWeb.APIDocsView do
"&#{param.key}=" <> "{<strong>#{param.placeholder}</strong>}" "&#{param.key}=" <> "{<strong>#{param.placeholder}</strong>}"
end) end)
end end
defp url do
if System.get_env("BLOCKSCOUT_HOST") do
"http://" <> System.get_env("BLOCKSCOUT_HOST")
else
Endpoint.url()
end
end
end end

@ -91,7 +91,7 @@ defmodule Explorer.SmartContract.Solidity.CodeCompiler do
"node", "node",
[ [
Application.app_dir(:explorer, "priv/compile_solc.js"), Application.app_dir(:explorer, "priv/compile_solc.js"),
code, create_source_file(code),
compiler_version, compiler_version,
optimize_value(optimize), optimize_value(optimize),
optimization_runs, optimization_runs,
@ -162,4 +162,12 @@ defmodule Explorer.SmartContract.Solidity.CodeCompiler do
defp optimize_value(true), do: "1" defp optimize_value(true), do: "1"
defp optimize_value("true"), do: "1" defp optimize_value("true"), do: "1"
defp create_source_file(source) do
{:ok, path} = Briefly.create()
File.write!(path, source)
path
end
end end

@ -107,6 +107,13 @@ defmodule Explorer.SmartContract.Verifier do
|> Enum.reverse() |> Enum.reverse()
|> :binary.list_to_bin() |> :binary.list_to_bin()
# Solidity >= 0.5.9; https://github.com/ethereum/solidity/blob/aa4ee3a1559ebc0354926af962efb3fcc7dc15bd/docs/metadata.rst
"a265627a7a72305820" <>
<<_::binary-size(64)>> <> "64736f6c6343" <> <<_::binary-size(6)>> <> "0032" <> _constructor_arguments ->
extracted
|> Enum.reverse()
|> :binary.list_to_bin()
<<next::binary-size(2)>> <> rest -> <<next::binary-size(2)>> <> rest ->
do_extract_bytecode([next | extracted], rest) do_extract_bytecode([next | extracted], rest)
end end

@ -21,6 +21,14 @@ defmodule Explorer.SmartContract.Verifier.ConstructorArguments do
constructor_arguments constructor_arguments
end end
# Solidity >= 0.5.9; https://github.com/ethereum/solidity/blob/aa4ee3a1559ebc0354926af962efb3fcc7dc15bd/docs/metadata.rst
defp extract_constructor_arguments(
"a265627a7a72305820" <>
<<_::binary-size(64)>> <> "64736f6c6343" <> <<_::binary-size(6)>> <> "0032" <> constructor_arguments
) do
constructor_arguments
end
defp extract_constructor_arguments(<<_::binary-size(2)>> <> rest) do defp extract_constructor_arguments(<<_::binary-size(2)>> <> rest) do
extract_constructor_arguments(rest) extract_constructor_arguments(rest)
end end

@ -66,6 +66,7 @@ defmodule Explorer.Mixfile do
# CSV output for benchee # CSV output for benchee
{:benchee_csv, "~> 0.8.0", only: :test}, {:benchee_csv, "~> 0.8.0", only: :test},
{:bypass, "~> 1.0", only: :test}, {:bypass, "~> 1.0", only: :test},
{:briefly, "~> 0.4", github: "CargoSense/briefly"},
{:comeonin, "~> 4.0"}, {:comeonin, "~> 4.0"},
{:credo, "1.0.0", only: :test, runtime: false}, {:credo, "1.0.0", only: :test, runtime: false},
# For Absinthe to load data in batches # For Absinthe to load data in batches

@ -1,6 +1,6 @@
#!/usr/bin/env node #!/usr/bin/env node
var sourceCode = process.argv[2]; var sourceCodePath = process.argv[2];
var version = process.argv[3]; var version = process.argv[3];
var optimize = process.argv[4]; var optimize = process.argv[4];
var optimizationRuns = parseInt(process.argv[5], 10); var optimizationRuns = parseInt(process.argv[5], 10);
@ -13,6 +13,9 @@ var solc = require('solc')
var compilerSnapshot = require(compilerVersionPath); var compilerSnapshot = require(compilerVersionPath);
var solc = solc.setupMethods(compilerSnapshot); var solc = solc.setupMethods(compilerSnapshot);
var fs = require('fs');
var sourceCode = fs.readFileSync(sourceCodePath, 'utf8');
const input = { const input = {
language: 'Solidity', language: 'Solidity',
sources: { sources: {

@ -268,6 +268,20 @@ defmodule Explorer.SmartContract.Solidity.CodeCompilerTest do
assert Enum.any?(abi, fn el -> el["type"] == "constructor" end) assert Enum.any?(abi, fn el -> el["type"] == "constructor" end)
end end
test "can compile a large file" do
path = File.cwd!() <> "/test/support/fixture/smart_contract/large_smart_contract.sol"
contract = File.read!(path)
assert {:ok, %{"abi" => abi}} =
CodeCompiler.run(
name: "HomeWorkDeployer",
compiler_version: "v0.5.9+commit.e560f70d",
code: contract,
evm_version: "constantinople",
optimize: true
)
end
end end
describe "get_contract_info/1" do describe "get_contract_info/1" do

File diff suppressed because one or more lines are too long

@ -0,0 +1,76 @@
pragma solidity ^0.5.9;
contract Token {
function totalSupply() public view returns (uint256 supply) {}
function balanceOf(address _owner) public view returns (uint256 balance) {}
function transfer(address _to, uint256 _value) public returns (bool success) {}
function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) {}
function approve(address _spender, uint256 _value) public returns (bool success) {}
function allowance(address _owner, address _spender) public view returns (uint256 remaining) {}
event Transfer(address indexed _from, address indexed _to, uint256 _value);
event Approval(address indexed _owner, address indexed _spender, uint256 _value);
}
contract StandardToken is Token {
function transfer(address _to, uint256 _value) public returns (bool success) {
//if (balances[msg.sender] >= _value && balances[_to] + _value > balances[_to]) {
if (balances[msg.sender] >= _value && _value > 0) {
balances[msg.sender] -= _value;
balances[_to] += _value;
emit Transfer(msg.sender, _to, _value);
return true;
} else { return false; }
}
function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) {
//if (balances[_from] >= _value && allowed[_from][msg.sender] >= _value && balances[_to] + _value > balances[_to]) {
if (balances[_from] >= _value && allowed[_from][msg.sender] >= _value && _value > 0) {
balances[_to] += _value;
balances[_from] -= _value;
allowed[_from][msg.sender] -= _value;
emit Transfer(_from, _to, _value);
return true;
} else { return false; }
}
function balanceOf(address _owner) public view returns (uint256 balance) {
return balances[_owner];
}
function approve(address _spender, uint256 _value) public returns (bool success) {
allowed[msg.sender][_spender] = _value;
emit Approval(msg.sender, _spender, _value);
return true;
}
function allowance(address _owner, address _spender) public view returns (uint256 remaining) {
return allowed[_owner][_spender];
}
mapping (address => uint256) balances;
mapping (address => mapping (address => uint256)) allowed;
uint256 totalTokenSupply;
}
contract TestToken is StandardToken {
/* Public variables */
string public name;
uint8 public decimals;
string public symbol;
string public version = '0.1';
constructor(
uint256 _initialAmount,
string memory _tokenName,
uint8 _decimalUnits,
string memory _tokenSymbol
) public {
balances[msg.sender] = _initialAmount;
totalTokenSupply = _initialAmount;
name = _tokenName;
decimals = _decimalUnits;
symbol = _tokenSymbol;
}
function approveAndCall(address _spender, uint256 _value) public returns (bool success) {
allowed[msg.sender][_spender] = _value;
emit Approval(msg.sender, _spender, _value);
return true;
}
}

@ -11,6 +11,7 @@
"benchee": {:hex, :benchee, "0.13.2", "30cd4ff5f593fdd218a9b26f3c24d580274f297d88ad43383afe525b1543b165", [:mix], [{:deep_merge, "~> 0.1", [hex: :deep_merge, repo: "hexpm", optional: false]}], "hexpm"}, "benchee": {:hex, :benchee, "0.13.2", "30cd4ff5f593fdd218a9b26f3c24d580274f297d88ad43383afe525b1543b165", [:mix], [{:deep_merge, "~> 0.1", [hex: :deep_merge, repo: "hexpm", optional: false]}], "hexpm"},
"benchee_csv": {:hex, :benchee_csv, "0.8.0", "0ca094677d6e2b2f601b7ee7864b754789ef9d24d079432e5e3d6f4fb83a4d80", [:mix], [{:benchee, "~> 0.12", [hex: :benchee, optional: false]}, {:csv, "~> 2.0", [hex: :csv, optional: false]}]}, "benchee_csv": {:hex, :benchee_csv, "0.8.0", "0ca094677d6e2b2f601b7ee7864b754789ef9d24d079432e5e3d6f4fb83a4d80", [:mix], [{:benchee, "~> 0.12", [hex: :benchee, optional: false]}, {:csv, "~> 2.0", [hex: :csv, optional: false]}]},
"binary": {:hex, :binary, "0.0.5", "20d816f7274ea34f1b673b4cff2fdb9ebec9391a7a68c349070d515c66b1b2cf", [:mix], []}, "binary": {:hex, :binary, "0.0.5", "20d816f7274ea34f1b673b4cff2fdb9ebec9391a7a68c349070d515c66b1b2cf", [:mix], []},
"briefly": {:git, "https://github.com/CargoSense/briefly.git", "2526e9674a4e6996137e066a1295ea60962712b8", []},
"bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], []}, "bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], []},
"bypass": {:hex, :bypass, "1.0.0", "b78b3dcb832a71aca5259c1a704b2e14b55fd4e1327ff942598b4e7d1a7ad83d", [:mix], [{:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 1.0 or ~> 2.0", [hex: :plug_cowboy, repo: "hexpm", optional: false]}], "hexpm"}, "bypass": {:hex, :bypass, "1.0.0", "b78b3dcb832a71aca5259c1a704b2e14b55fd4e1327ff942598b4e7d1a7ad83d", [:mix], [{:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 1.0 or ~> 2.0", [hex: :plug_cowboy, repo: "hexpm", optional: false]}], "hexpm"},
"certifi": {:hex, :certifi, "2.5.1", "867ce347f7c7d78563450a18a6a28a8090331e77fa02380b4a21962a65d36ee5", [:rebar3], [{:parse_trans, "~>3.3", [hex: :parse_trans, repo: "hexpm", optional: false]}], "hexpm"}, "certifi": {:hex, :certifi, "2.5.1", "867ce347f7c7d78563450a18a6a28a8090331e77fa02380b4a21962a65d36ee5", [:rebar3], [{:parse_trans, "~>3.3", [hex: :parse_trans, repo: "hexpm", optional: false]}], "hexpm"},

Loading…
Cancel
Save