Add vyper support for rust verifier microservice integration

pull/6073/head
Никита Поздняков 2 years ago
parent 24f536f24a
commit 50ca4449d6
No known key found for this signature in database
GPG Key ID: F344106F9804FE5F
  1. 1
      CHANGELOG.md
  2. 20
      apps/explorer/lib/explorer/smart_contract/compiler_version.ex
  3. 21
      apps/explorer/lib/explorer/smart_contract/rust_verifier_interface.ex
  4. 4
      apps/explorer/lib/explorer/smart_contract/solidity/verifier.ex
  5. 25
      apps/explorer/lib/explorer/smart_contract/vyper/publisher.ex
  6. 35
      apps/explorer/lib/explorer/smart_contract/vyper/verifier.ex

@ -1,6 +1,7 @@
## Current
### Features
- [#6073](https://github.com/blockscout/blockscout/pull/6073) - Add vyper support for rust verifier microservice integration
### Fixes

@ -39,17 +39,21 @@ defmodule Explorer.SmartContract.CompilerVersion do
end
defp fetch_vyper_versions do
headers = [{"Content-Type", "application/json"}]
if RustVerifierInterface.enabled?() do
RustVerifierInterface.vyper_get_versions_list()
else
headers = [{"Content-Type", "application/json"}]
case HTTPoison.get(source_url(:vyper), headers) do
{:ok, %{status_code: 200, body: body}} ->
{:ok, format_data(body, :vyper)}
case HTTPoison.get(source_url(:vyper), headers) do
{:ok, %{status_code: 200, body: body}} ->
{:ok, format_data(body, :vyper)}
{:ok, %{status_code: _status_code, body: body}} ->
{:error, decode_json(body)["error"]}
{:ok, %{status_code: _status_code, body: body}} ->
{:error, decode_json(body)["error"]}
{:error, %{reason: reason}} ->
{:error, reason}
{:error, %{reason: reason}} ->
{:error, reason}
end
end
end

@ -1,6 +1,6 @@
defmodule Explorer.SmartContract.RustVerifierInterface do
@moduledoc """
Adapter for contracts verification with https://github.com/blockscout/blockscout-rs/tree/main/verification
Adapter for contracts verification with https://github.com/blockscout/blockscout-rs/blob/main/smart-contract-verifier
"""
alias HTTPoison.Response
require Logger
@ -33,6 +33,17 @@ defmodule Explorer.SmartContract.RustVerifierInterface do
http_post_request(standard_json_input_verification_url(), body)
end
def vyper_verify_multipart(
%{
"creation_bytecode" => _,
"deployed_bytecode" => _,
"compiler_version" => _,
"sources" => _
} = body
) do
http_post_request(vyper_multiple_files_verification_url(), body)
end
def http_post_request(url, body) do
headers = [{"Content-Type", "application/json"}]
@ -79,6 +90,10 @@ defmodule Explorer.SmartContract.RustVerifierInterface do
http_get_request(versions_list_url())
end
def vyper_get_versions_list do
http_get_request(vyper_versions_list_url())
end
def proccess_verifier_response(body) when is_binary(body) do
case Jason.decode(body) do
{:ok, decoded} ->
@ -103,10 +118,14 @@ defmodule Explorer.SmartContract.RustVerifierInterface do
def multiple_files_verification_url, do: "#{base_api_url()}" <> "/solidity/verify/multiple-files"
def vyper_multiple_files_verification_url, do: "#{base_api_url()}" <> "/vyper/verify/multiple-files"
def standard_json_input_verification_url, do: "#{base_api_url()}" <> "/solidity/verify/standard-json"
def versions_list_url, do: "#{base_api_url()}" <> "/solidity/versions"
def vyper_versions_list_url, do: "#{base_api_url()}" <> "/vyper/versions"
def base_api_url, do: "#{base_url()}" <> "/api/v1"
def base_url do

@ -36,7 +36,7 @@ defmodule Explorer.SmartContract.Solidity.Verifier do
end
end
def evaluate_authenticity_inner(true, address_hash, params) do
defp evaluate_authenticity_inner(true, address_hash, params) do
deployed_bytecode = Chain.smart_contract_bytecode(address_hash)
creation_tx_input =
@ -57,7 +57,7 @@ defmodule Explorer.SmartContract.Solidity.Verifier do
|> RustVerifierInterface.verify_multi_part()
end
def evaluate_authenticity_inner(false, address_hash, params) do
defp evaluate_authenticity_inner(false, address_hash, params) do
latest_evm_version = List.last(CodeCompiler.allowed_evm_versions())
evm_version = Map.get(params, "evm_version", latest_evm_version)

@ -10,6 +10,31 @@ defmodule Explorer.SmartContract.Vyper.Publisher do
def publish(address_hash, params) do
case Verifier.evaluate_authenticity(address_hash, params) do
{
:ok,
%{
"abi" => abi_string,
"compiler_version" => _,
"constructor_arguments" => _,
"contract_libraries" => contract_libraries,
"contract_name" => contract_name,
"evm_version" => _,
"file_name" => file_name,
"optimization" => _,
"optimization_runs" => _,
"sources" => sources
} = result_params
} ->
%{^file_name => contract_source_code} = sources
prepared_params =
result_params
|> Map.put("contract_source_code", contract_source_code)
|> Map.put("external_libraries", contract_libraries)
|> Map.put("name", contract_name)
publish_smart_contract(address_hash, prepared_params, Jason.decode!(abi_string))
{:ok, %{abi: abi}} ->
publish_smart_contract(address_hash, params, abi)

@ -7,9 +7,11 @@ defmodule Explorer.SmartContract.Vyper.Verifier do
against the existing Creation Address Bytecode, if it matches the contract is
then Verified.
"""
require Logger
alias Explorer.Chain
alias Explorer.SmartContract.Vyper.CodeCompiler
alias Explorer.SmartContract.RustVerifierInterface
def evaluate_authenticity(_, %{"name" => ""}), do: {:error, :name}
@ -17,6 +19,39 @@ defmodule Explorer.SmartContract.Vyper.Verifier do
do: {:error, :contract_source_code}
def evaluate_authenticity(address_hash, params) do
try do
evaluate_authenticity_inner(RustVerifierInterface.enabled?(), address_hash, params)
rescue
exception ->
Logger.error(fn ->
[
"Error while verifying smart-contract address: #{address_hash}, params: #{inspect(params, limit: :infinity, printable_limit: :infinity)}: ",
Exception.format(:error, exception)
]
end)
end
end
defp evaluate_authenticity_inner(true, address_hash, params) do
deployed_bytecode = Chain.smart_contract_bytecode(address_hash)
creation_tx_input =
case Chain.smart_contract_creation_tx_bytecode(address_hash) do
%{init: init, created_contract_code: _created_contract_code} ->
init
_ ->
""
end
params
|> Map.put("creation_bytecode", creation_tx_input)
|> Map.put("deployed_bytecode", deployed_bytecode)
|> Map.put("sources", %{"#{params["name"]}.vy" => params["contract_source_code"]})
|> RustVerifierInterface.vyper_verify_multipart()
end
defp evaluate_authenticity_inner(false, address_hash, params) do
verify(address_hash, params)
end

Loading…
Cancel
Save