|
|
|
@ -11,8 +11,10 @@ defmodule Explorer.SmartContract.Solidity.Verifier do |
|
|
|
|
import Explorer.SmartContract.Helper, |
|
|
|
|
only: [cast_libraries: 1, prepare_bytecode_for_microservice: 3, contract_creation_input: 1] |
|
|
|
|
|
|
|
|
|
# import Explorer.Chain.SmartContract, only: [:function_description] |
|
|
|
|
alias ABI.{FunctionSelector, TypeDecoder} |
|
|
|
|
alias Explorer.Chain |
|
|
|
|
alias Explorer.Chain.{Data, Hash, SmartContract} |
|
|
|
|
alias Explorer.SmartContract.RustVerifierInterface |
|
|
|
|
alias Explorer.SmartContract.Solidity.CodeCompiler |
|
|
|
|
|
|
|
|
@ -533,4 +535,53 @@ defmodule Explorer.SmartContract.Solidity.Verifier do |
|
|
|
|
def parse_boolean(false), do: false |
|
|
|
|
|
|
|
|
|
def parse_boolean(_), do: false |
|
|
|
|
|
|
|
|
|
@doc """ |
|
|
|
|
Function tries to parse constructor args from smart contract creation input. |
|
|
|
|
1. using `extract_meta_from_deployed_bytecode/1` we derive CBOR metadata string |
|
|
|
|
2. using metadata we split creation_tx_input and try to decode resulting constructor arguments |
|
|
|
|
2.1. if we successfully decoded args using constructor's abi, then return constructor args |
|
|
|
|
2.2 otherwise return nil |
|
|
|
|
""" |
|
|
|
|
@spec parse_constructor_arguments_for_sourcify_contract(Hash.Address.t(), SmartContract.abi()) :: nil | binary |
|
|
|
|
def parse_constructor_arguments_for_sourcify_contract(address_hash, abi) do |
|
|
|
|
parse_constructor_arguments_for_sourcify_contract(address_hash, abi, Chain.smart_contract_bytecode(address_hash)) |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
@doc """ |
|
|
|
|
Clause for cases when we already can pass deployed bytecode to this function (in order to avoid excessive read DB accesses) |
|
|
|
|
""" |
|
|
|
|
@spec parse_constructor_arguments_for_sourcify_contract( |
|
|
|
|
Hash.Address.t(), |
|
|
|
|
SmartContract.abi(), |
|
|
|
|
binary | Explorer.Chain.Data.t() |
|
|
|
|
) :: nil | binary |
|
|
|
|
def parse_constructor_arguments_for_sourcify_contract(address_hash, abi, deployed_bytecode) |
|
|
|
|
when is_binary(deployed_bytecode) do |
|
|
|
|
creation_tx_input = |
|
|
|
|
case Chain.smart_contract_creation_tx_bytecode(address_hash) do |
|
|
|
|
%{init: init, created_contract_code: _created_contract_code} -> |
|
|
|
|
"0x" <> init_without_0x = init |
|
|
|
|
init_without_0x |
|
|
|
|
|
|
|
|
|
_ -> |
|
|
|
|
nil |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
with true <- has_constructor_with_params?(abi), |
|
|
|
|
check_function <- parse_constructor_and_return_check_function(abi), |
|
|
|
|
false <- is_nil(creation_tx_input) || deployed_bytecode == "0x", |
|
|
|
|
{meta, meta_length} <- extract_meta_from_deployed_bytecode(deployed_bytecode), |
|
|
|
|
[_bytecode, constructor_args] <- String.split(creation_tx_input, meta <> meta_length), |
|
|
|
|
^constructor_args <- check_function.(constructor_args) do |
|
|
|
|
constructor_args |
|
|
|
|
else |
|
|
|
|
_ -> |
|
|
|
|
nil |
|
|
|
|
end |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
def parse_constructor_arguments_for_sourcify_contract(address_hash, abi, deployed_bytecode) do |
|
|
|
|
parse_constructor_arguments_for_sourcify_contract(address_hash, abi, Data.to_string(deployed_bytecode)) |
|
|
|
|
end |
|
|
|
|
end |
|
|
|
|