Merge branch 'master' into ag-minor-update

pull/1407/head
Andrew Cravenho 6 years ago committed by GitHub
commit 01488c57f1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/parity/fetched_beneficiaries.ex
  2. 21
      apps/explorer/lib/explorer/smart_contract/solidity/code_compiler.ex
  3. 5
      apps/explorer/priv/compile_solc.js
  4. 37
      apps/explorer/test/explorer/smart_contract/solidity/code_compiler_test.exs
  5. 22
      apps/explorer/test/support/fixture/smart_contract/compiler_tests.json
  6. 3
      docker/Dockerfile
  7. 2
      docker/Makefile

@ -171,6 +171,7 @@ defmodule EthereumJSONRPC.Parity.FetchedBeneficiaries do
# The rewardType "uncle" will show reward for validating an uncle block
defp get_address_type(reward_type, index) when reward_type == "external" and index == 0, do: :validator
defp get_address_type(reward_type, index) when reward_type == "external" and index == 1, do: :emission_funds
defp get_address_type(reward_type, index) when reward_type == "external" and index == 2, do: :validator
defp get_address_type(reward_type, _index) when reward_type == "block", do: :validator
defp get_address_type(reward_type, _index) when reward_type == "uncle", do: :uncle
end

@ -3,6 +3,8 @@ defmodule Explorer.SmartContract.Solidity.CodeCompiler do
Module responsible to compile the Solidity code of a given Smart Contract.
"""
@new_contract_name "New.sol"
@doc """
Compiles a code in the solidity command line.
@ -58,7 +60,7 @@ defmodule Explorer.SmartContract.Solidity.CodeCompiler do
}
}
"""
def run(name, compiler_version, code, optimize) do
def run(name, compiler_version, code, optimize, external_libs \\ %{}) do
{response, _status} =
System.cmd(
"node",
@ -66,14 +68,17 @@ defmodule Explorer.SmartContract.Solidity.CodeCompiler do
Application.app_dir(:explorer, "priv/compile_solc.js"),
code,
compiler_version,
optimize_value(optimize)
optimize_value(optimize),
@new_contract_name
]
)
with {:ok, contracts} <- Jason.decode(response),
%{"abi" => abi, "evm" => %{"deployedBytecode" => %{"object" => bytecode}}} <-
get_contract_info(contracts, name) do
{:ok, %{"abi" => abi, "bytecode" => bytecode, "name" => name}}
bytecode_with_libraries = add_library_addresses(bytecode, external_libs)
{:ok, %{"abi" => abi, "bytecode" => bytecode_with_libraries, "name" => name}}
else
{:error, %Jason.DecodeError{}} ->
{:error, :compilation}
@ -100,6 +105,16 @@ defmodule Explorer.SmartContract.Solidity.CodeCompiler do
end
end
defp add_library_addresses(bytecode, external_libs) do
Enum.reduce(external_libs, bytecode, fn {library_name, address}, acc ->
placeholder = String.replace(@new_contract_name, ".", "\.") <> ":" <> library_name
regex = Regex.compile!("_+#{placeholder}_+")
address = String.replace(address, "0x", "")
String.replace(acc, regex, address)
end)
end
def parse_error(%{"error" => error}), do: {:error, [error]}
def parse_error(%{"errors" => errors}), do: {:error, errors}
def parse_error({:error, _} = error), do: error

@ -5,6 +5,7 @@ const solc = require('solc');
var sourceCode = process.argv[2];
var version = process.argv[3];
var optimize = process.argv[4];
var newContractName = process.argv[5];
var compiled_code = solc.loadRemoteVersion(version, function (err, solcSnapshot) {
if (err) {
@ -13,7 +14,7 @@ var compiled_code = solc.loadRemoteVersion(version, function (err, solcSnapshot)
const input = {
language: 'Solidity',
sources: {
'New.sol': {
[newContractName]: {
content: sourceCode
}
},
@ -33,7 +34,7 @@ var compiled_code = solc.loadRemoteVersion(version, function (err, solcSnapshot)
const output = JSON.parse(solcSnapshot.compile(JSON.stringify(input)))
/** Older solc-bin versions don't use filename as contract key */
const response = output.contracts['New.sol'] || output.contracts['']
const response = output.contracts[newContractName] || output.contracts['']
console.log(JSON.stringify(response));
}
});

@ -3,8 +3,12 @@ defmodule Explorer.SmartContract.Solidity.CodeCompilerTest do
doctest Explorer.SmartContract.Solidity.CodeCompiler
alias Explorer.SmartContract.Solidity.CodeCompiler
alias Explorer.Factory
alias Explorer.SmartContract.Solidity.CodeCompiler
@compiler_tests "#{System.cwd!()}/test/support/fixture/smart_contract/compiler_tests.json"
|> File.read!()
|> Jason.decode!()
describe "run/2" do
setup do
@ -47,6 +51,30 @@ defmodule Explorer.SmartContract.Solidity.CodeCompilerTest do
}} = response
end
test "compiles code with external libraries" do
Enum.each(@compiler_tests, fn compiler_test ->
compiler_version = compiler_test["compiler_version"]
external_libraries = compiler_test["external_libraries"]
name = compiler_test["name"]
optimize = compiler_test["optimize"]
contract = compiler_test["contract"]
{:ok, result} =
CodeCompiler.run(
name,
compiler_version,
contract,
optimize,
external_libraries
)
clean_result = remove_init_data_and_whisper_data(result["bytecode"])
expected_result = remove_init_data_and_whisper_data(compiler_test["expected_bytecode"])
assert clean_result == expected_result
end)
end
test "compile in an older solidity version" do
optimize = false
name = "SimpleStorage"
@ -133,4 +161,11 @@ defmodule Explorer.SmartContract.Solidity.CodeCompilerTest do
assert contract_inner_info == response
end
end
defp remove_init_data_and_whisper_data(code) do
code
|> String.split("0029")
|> List.first()
|> String.split_at(-64)
end
end

File diff suppressed because one or more lines are too long

@ -19,6 +19,9 @@ RUN mix do deps.get, deps.compile
ADD . .
ARG COIN
RUN if [ "$COIN" != "" ]; then sed -i s/"POA"/"${COIN}"/g apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po; fi
# Run forderground build and phoenix digest
RUN mix compile

@ -53,7 +53,7 @@ ifdef HAS_BLOCKSCOUT_IMAGE
@echo "==> Image exist. Using $(DOCKER_IMAGE)"
else
@echo "==> No image found trying to build one..."
@docker build -f ./Dockerfile -t $(DOCKER_IMAGE) ../
@docker build --build-arg COIN="$(COIN)" -f ./Dockerfile -t $(DOCKER_IMAGE) ../
endif
migrate: build postgres

Loading…
Cancel
Save