Extend getsourcecode API view with new output fields

pull/2857/head
Victor Baranov 5 years ago
parent 7286cbfa60
commit b5bce41ab9
  1. 1
      CHANGELOG.md
  2. 96
      apps/block_scout_web/lib/block_scout_web/views/api/rpc/contract_view.ex
  3. 65
      apps/block_scout_web/test/block_scout_web/controllers/api/rpc/contract_controller_test.exs

@ -1,6 +1,7 @@
## Current
### Features
- [#2857](https://github.com/poanetwork/blockscout/pull/2857) - Extend getsourcecode API view with new output fields
- [#2787](https://github.com/poanetwork/blockscout/pull/2787) - async fetching of address counters
- [#2791](https://github.com/poanetwork/blockscout/pull/2791) - add ipc client
- [#2449](https://github.com/poanetwork/blockscout/pull/2449) - add ability to send notification events through postgres notify

@ -35,7 +35,11 @@ defmodule BlockScoutWeb.API.RPC.ContractView do
"CompilerVersion" => "",
"DecompiledSourceCode" => "",
"DecompilerVersion" => decompiler_version(nil),
"OptimizationUsed" => ""
"OptimizationUsed" => "",
"OptimizationRuns" => "",
"EVMVersion" => "",
"ConstructorArguments" => "",
"ExternalLibraries" => ""
}
end
@ -43,6 +47,64 @@ defmodule BlockScoutWeb.API.RPC.ContractView do
decompiled_smart_contract = latest_decompiled_smart_contract(address.decompiled_smart_contracts)
contract = address.smart_contract || %{}
optimization = Map.get(contract, :optimization, "")
contract_output = %{
"Address" => to_string(address.hash)
}
contract_output
|> set_decompiled_contract_data(decompiled_smart_contract)
|> set_optimization_runs(contract, optimization)
|> set_constructor_arguments(contract)
|> set_external_libraries(contract)
|> set_verified_contract_data(contract, address, optimization)
end
defp set_decompiled_contract_data(contract_output, decompiled_smart_contract) do
if decompiled_smart_contract do
contract_output
|> Map.put_new(:DecompiledSourceCode, decompiled_source_code(decompiled_smart_contract))
|> Map.put_new(:DecompilerVersion, decompiler_version(decompiled_smart_contract))
else
contract_output
end
end
defp set_optimization_runs(contract_output, contract, optimization) do
optimization_runs = Map.get(contract, :optimization_runs, "")
if optimization && optimization != "" do
contract_output
|> Map.put_new(:OptimizationRuns, optimization_runs)
else
contract_output
end
end
defp set_constructor_arguments(contract_output, contract) do
constructor_arguments = Map.get(contract, :constructor_arguments, "")
if constructor_arguments && constructor_arguments != "" do
contract_output
|> Map.put_new(:ConstructorArguments, constructor_arguments)
else
contract_output
end
end
defp set_external_libraries(contract_output, contract) do
external_libraries = Map.get(contract, :external_libraries, [])
if Enum.count(external_libraries) > 0 do
contract_output
|> Map.put_new(:ExternalLibraries, external_libraries)
else
contract_output
end
end
defp set_verified_contract_data(contract_output, contract, address, optimization) do
contract_abi =
if is_nil(address.smart_contract) do
"Contract source code not verified"
@ -51,27 +113,28 @@ defmodule BlockScoutWeb.API.RPC.ContractView do
end
contract_optimization =
case Map.get(contract, :optimization, "") do
case optimization do
true ->
"1"
"true"
false ->
"0"
"false"
"" ->
""
end
%{
"Address" => to_string(address.hash),
"SourceCode" => Map.get(contract, :contract_source_code, ""),
"ABI" => contract_abi,
"ContractName" => Map.get(contract, :name, ""),
"DecompiledSourceCode" => decompiled_source_code(decompiled_smart_contract),
"DecompilerVersion" => decompiler_version(decompiled_smart_contract),
"CompilerVersion" => Map.get(contract, :compiler_version, ""),
"OptimizationUsed" => contract_optimization
}
if Map.equal?(contract, %{}) do
contract_output
else
contract_output
|> Map.put_new(:SourceCode, Map.get(contract, :contract_source_code, ""))
|> Map.put_new(:ABI, contract_abi)
|> Map.put_new(:ContractName, Map.get(contract, :name, ""))
|> Map.put_new(:CompilerVersion, Map.get(contract, :compiler_version, ""))
|> Map.put_new(:OptimizationUsed, contract_optimization)
|> Map.put_new(:EVMVersion, Map.get(contract, :evm_version, ""))
end
end
defp prepare_contract(%Address{
@ -80,10 +143,7 @@ defmodule BlockScoutWeb.API.RPC.ContractView do
}) do
%{
"Address" => to_string(hash),
"ABI" => "Contract source code not verified",
"ContractName" => "",
"CompilerVersion" => "",
"OptimizationUsed" => ""
"ABI" => "Contract source code not verified"
}
end

@ -70,10 +70,7 @@ defmodule BlockScoutWeb.API.RPC.ContractControllerTest do
assert response["result"] == [
%{
"ABI" => "Contract source code not verified",
"Address" => to_string(address.hash),
"CompilerVersion" => "",
"ContractName" => "",
"OptimizationUsed" => ""
"Address" => to_string(address.hash)
}
]
@ -95,10 +92,7 @@ defmodule BlockScoutWeb.API.RPC.ContractControllerTest do
assert response["result"] == [
%{
"ABI" => "Contract source code not verified",
"Address" => to_string(address.hash),
"CompilerVersion" => "",
"ContractName" => "",
"OptimizationUsed" => ""
"Address" => to_string(address.hash)
}
]
@ -124,10 +118,7 @@ defmodule BlockScoutWeb.API.RPC.ContractControllerTest do
assert response["result"] == [
%{
"ABI" => "Contract source code not verified",
"Address" => to_string(address.hash),
"CompilerVersion" => "",
"ContractName" => "",
"OptimizationUsed" => ""
"Address" => to_string(address.hash)
}
]
@ -174,10 +165,7 @@ defmodule BlockScoutWeb.API.RPC.ContractControllerTest do
assert response["result"] == [
%{
"ABI" => "Contract source code not verified",
"Address" => to_string(decompiled_smart_contract.address_hash),
"CompilerVersion" => "",
"ContractName" => "",
"OptimizationUsed" => ""
"Address" => to_string(decompiled_smart_contract.address_hash)
}
]
@ -199,10 +187,7 @@ defmodule BlockScoutWeb.API.RPC.ContractControllerTest do
assert response["result"] == [
%{
"ABI" => "Contract source code not verified",
"Address" => to_string(smart_contract.address_hash),
"CompilerVersion" => "",
"ContractName" => "",
"OptimizationUsed" => ""
"Address" => to_string(smart_contract.address_hash)
}
]
@ -225,10 +210,7 @@ defmodule BlockScoutWeb.API.RPC.ContractControllerTest do
assert %{
"ABI" => "Contract source code not verified",
"Address" => to_string(smart_contract.address_hash),
"CompilerVersion" => "",
"ContractName" => "",
"OptimizationUsed" => ""
"Address" => to_string(smart_contract.address_hash)
} in response["result"]
refute to_string(non_match.address_hash) in Enum.map(response["result"], &Map.get(&1, "Address"))
@ -251,10 +233,7 @@ defmodule BlockScoutWeb.API.RPC.ContractControllerTest do
assert response["result"] == [
%{
"ABI" => "Contract source code not verified",
"Address" => to_string(contract_address.hash),
"CompilerVersion" => "",
"ContractName" => "",
"OptimizationUsed" => ""
"Address" => to_string(contract_address.hash)
}
]
@ -281,10 +260,7 @@ defmodule BlockScoutWeb.API.RPC.ContractControllerTest do
assert response["result"] == [
%{
"ABI" => "Contract source code not verified",
"Address" => to_string(contract_address.hash),
"CompilerVersion" => "",
"ContractName" => "",
"OptimizationUsed" => ""
"Address" => to_string(contract_address.hash)
}
]
@ -423,7 +399,11 @@ defmodule BlockScoutWeb.API.RPC.ContractControllerTest do
"CompilerVersion" => "",
"OptimizationUsed" => "",
"DecompiledSourceCode" => "",
"DecompilerVersion" => ""
"DecompilerVersion" => "",
"ConstructorArguments" => "",
"EVMVersion" => "",
"ExternalLibraries" => "",
"OptimizationRuns" => ""
}
]
@ -439,7 +419,7 @@ defmodule BlockScoutWeb.API.RPC.ContractControllerTest do
end
test "with a verified contract address", %{conn: conn} do
contract = insert(:smart_contract, optimization: true)
contract = insert(:smart_contract, optimization: true, optimization_runs: 200, evm_version: "default")
params = %{
"module" => "contract",
@ -456,12 +436,12 @@ defmodule BlockScoutWeb.API.RPC.ContractControllerTest do
"ABI" => Jason.encode!(contract.abi),
"ContractName" => contract.name,
"CompilerVersion" => contract.compiler_version,
"DecompiledSourceCode" => "Contract source code not decompiled.",
# The contract's optimization value is true, so the expected value
# for `OptimizationUsed` is "1". If it was false, the expected value
# would be "0".
"DecompilerVersion" => "",
"OptimizationUsed" => "1"
"OptimizationUsed" => "true",
"OptimizationRuns" => 200,
"EVMVersion" => "default"
}
]
@ -508,9 +488,8 @@ defmodule BlockScoutWeb.API.RPC.ContractControllerTest do
"ABI" => Jason.encode!(contract_code_info.abi),
"ContractName" => contract_code_info.name,
"CompilerVersion" => contract_code_info.version,
"DecompiledSourceCode" => "Contract source code not decompiled.",
"DecompilerVersion" => "",
"OptimizationUsed" => "0"
"OptimizationUsed" => "false",
"EVMVersion" => nil
}
assert response["status"] == "1"
@ -578,9 +557,9 @@ defmodule BlockScoutWeb.API.RPC.ContractControllerTest do
contract_source_code
assert result["ContractName"] == name
assert result["DecompiledSourceCode"] == "Contract source code not decompiled."
assert result["DecompilerVersion"] == ""
assert result["OptimizationUsed"] == "1"
assert result["DecompiledSourceCode"] == nil
assert result["DecompilerVersion"] == nil
assert result["OptimizationUsed"] == "true"
assert :ok = ExJsonSchema.Validator.validate(verify_schema(), response)
end
end

Loading…
Cancel
Save