feat: Support smart-contract verification in zkSync (#10500)
* db changes for zksync smart-contract verification support * Update SmartContract model * Pass zk_compiler_version value in API v1/v2 endpoints * Extend sc verification config with config for zk compilers * Fix constructor arguments saving * Enhance api/v2/smart-contracts/verification/config for zkSync * Process review comments * creationMatch -> runtimeMatch * Fix merging conflicts * Finishing touchespull/10604/head
parent
5d98e8ba33
commit
c4a13a726e
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@ -0,0 +1,10 @@ |
|||||||
|
defmodule Explorer.Repo.ZkSync.Migrations.AddZkCompilerVersionToSmartContracts do |
||||||
|
use Ecto.Migration |
||||||
|
|
||||||
|
def change do |
||||||
|
alter table(:smart_contracts) do |
||||||
|
add(:zk_compiler_version, :string, null: true) |
||||||
|
modify(:optimization_runs, :string, null: true) |
||||||
|
end |
||||||
|
end |
||||||
|
end |
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,80 +1,82 @@ |
|||||||
defmodule Explorer.SmartContract.Vyper.PublisherTest do |
if Application.compile_env(:explorer, :chain_type) !== :zksync do |
||||||
use ExUnit.Case, async: true |
defmodule Explorer.SmartContract.Vyper.PublisherTest do |
||||||
|
use ExUnit.Case, async: true |
||||||
|
|
||||||
use Explorer.DataCase |
use Explorer.DataCase |
||||||
|
|
||||||
doctest Explorer.SmartContract.Vyper.Publisher |
doctest Explorer.SmartContract.Vyper.Publisher |
||||||
|
|
||||||
@moduletag timeout: :infinity |
@moduletag timeout: :infinity |
||||||
|
|
||||||
alias Explorer.Chain.{SmartContract} |
alias Explorer.Chain.{SmartContract} |
||||||
alias Explorer.Factory |
alias Explorer.Factory |
||||||
alias Explorer.SmartContract.Vyper.Publisher |
alias Explorer.SmartContract.Vyper.Publisher |
||||||
|
|
||||||
setup do |
setup do |
||||||
configuration = Application.get_env(:explorer, Explorer.SmartContract.RustVerifierInterfaceBehaviour) |
configuration = Application.get_env(:explorer, Explorer.SmartContract.RustVerifierInterfaceBehaviour) |
||||||
Application.put_env(:explorer, Explorer.SmartContract.RustVerifierInterfaceBehaviour, enabled: false) |
Application.put_env(:explorer, Explorer.SmartContract.RustVerifierInterfaceBehaviour, enabled: false) |
||||||
|
|
||||||
on_exit(fn -> |
on_exit(fn -> |
||||||
Application.put_env(:explorer, Explorer.SmartContract.RustVerifierInterfaceBehaviour, configuration) |
Application.put_env(:explorer, Explorer.SmartContract.RustVerifierInterfaceBehaviour, configuration) |
||||||
end) |
end) |
||||||
end |
end |
||||||
|
|
||||||
describe "publish/2" do |
describe "publish/2" do |
||||||
test "with valid data creates a smart_contract" do |
test "with valid data creates a smart_contract" do |
||||||
contract_code_info = Factory.contract_code_info_vyper() |
contract_code_info = Factory.contract_code_info_vyper() |
||||||
|
|
||||||
contract_address = insert(:contract_address, contract_code: contract_code_info.bytecode) |
contract_address = insert(:contract_address, contract_code: contract_code_info.bytecode) |
||||||
|
|
||||||
:transaction |
:transaction |
||||||
|> insert(created_contract_address_hash: contract_address.hash, input: contract_code_info.tx_input) |
|> insert(created_contract_address_hash: contract_address.hash, input: contract_code_info.tx_input) |
||||||
|> with_block(status: :ok) |
|> with_block(status: :ok) |
||||||
|
|
||||||
valid_attrs = %{ |
valid_attrs = %{ |
||||||
"contract_source_code" => contract_code_info.source_code, |
"contract_source_code" => contract_code_info.source_code, |
||||||
"compiler_version" => contract_code_info.version, |
"compiler_version" => contract_code_info.version, |
||||||
"name" => contract_code_info.name |
"name" => contract_code_info.name |
||||||
} |
} |
||||||
|
|
||||||
response = Publisher.publish(contract_address.hash, valid_attrs) |
response = Publisher.publish(contract_address.hash, valid_attrs) |
||||||
assert {:ok, %SmartContract{} = smart_contract} = response |
assert {:ok, %SmartContract{} = smart_contract} = response |
||||||
|
|
||||||
assert smart_contract.address_hash == contract_address.hash |
assert smart_contract.address_hash == contract_address.hash |
||||||
assert smart_contract.name == valid_attrs["name"] |
assert smart_contract.name == valid_attrs["name"] |
||||||
assert smart_contract.compiler_version == valid_attrs["compiler_version"] |
assert smart_contract.compiler_version == valid_attrs["compiler_version"] |
||||||
assert smart_contract.contract_source_code == valid_attrs["contract_source_code"] |
assert smart_contract.contract_source_code == valid_attrs["contract_source_code"] |
||||||
assert is_nil(smart_contract.constructor_arguments) |
assert is_nil(smart_contract.constructor_arguments) |
||||||
assert smart_contract.abi == contract_code_info.abi |
assert smart_contract.abi == contract_code_info.abi |
||||||
end |
end |
||||||
|
|
||||||
test "allows to re-verify vyper contracts" do |
test "allows to re-verify vyper contracts" do |
||||||
contract_code_info = Factory.contract_code_info_vyper() |
contract_code_info = Factory.contract_code_info_vyper() |
||||||
|
|
||||||
contract_address = insert(:contract_address, contract_code: contract_code_info.bytecode) |
contract_address = insert(:contract_address, contract_code: contract_code_info.bytecode) |
||||||
|
|
||||||
:transaction |
:transaction |
||||||
|> insert(created_contract_address_hash: contract_address.hash, input: contract_code_info.tx_input) |
|> insert(created_contract_address_hash: contract_address.hash, input: contract_code_info.tx_input) |
||||||
|> with_block(status: :ok) |
|> with_block(status: :ok) |
||||||
|
|
||||||
valid_attrs = %{ |
valid_attrs = %{ |
||||||
"contract_source_code" => contract_code_info.source_code, |
"contract_source_code" => contract_code_info.source_code, |
||||||
"compiler_version" => contract_code_info.version, |
"compiler_version" => contract_code_info.version, |
||||||
"name" => contract_code_info.name |
"name" => contract_code_info.name |
||||||
} |
} |
||||||
|
|
||||||
response = Publisher.publish(contract_address.hash, valid_attrs) |
response = Publisher.publish(contract_address.hash, valid_attrs) |
||||||
assert {:ok, %SmartContract{}} = response |
assert {:ok, %SmartContract{}} = response |
||||||
|
|
||||||
updated_name = "AnotherContractName" |
updated_name = "AnotherContractName" |
||||||
|
|
||||||
valid_attrs = |
valid_attrs = |
||||||
valid_attrs |
valid_attrs |
||||||
|> Map.put("name", updated_name) |
|> Map.put("name", updated_name) |
||||||
|
|
||||||
response = Publisher.publish(contract_address.hash, valid_attrs) |
response = Publisher.publish(contract_address.hash, valid_attrs) |
||||||
assert {:ok, %SmartContract{} = smart_contract} = response |
assert {:ok, %SmartContract{} = smart_contract} = response |
||||||
|
|
||||||
assert smart_contract.name == valid_attrs["name"] |
assert smart_contract.name == valid_attrs["name"] |
||||||
|
end |
||||||
end |
end |
||||||
end |
end |
||||||
end |
end |
||||||
|
Loading…
Reference in new issue