Merge pull request #5248 from blockscout/vb-fix-slow-contract-code-verified-candidate

Speedup query for getting verified smart-contract bytecode twin
pull/5260/head
Victor Baranov 3 years ago committed by GitHub
commit ec75ba407b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      CHANGELOG.md
  2. 2
      apps/block_scout_web/test/block_scout_web/controllers/address_read_contract_controller_test.exs
  3. 2
      apps/block_scout_web/test/block_scout_web/controllers/address_read_proxy_controller_test.exs
  4. 2
      apps/block_scout_web/test/block_scout_web/controllers/address_write_contract_controller_test.exs
  5. 2
      apps/block_scout_web/test/block_scout_web/controllers/address_write_proxy_controller_test.exs
  6. 25
      apps/block_scout_web/test/block_scout_web/controllers/api/rpc/contract_controller_test.exs
  7. 12
      apps/block_scout_web/test/block_scout_web/controllers/chain_controller_test.exs
  8. 17
      apps/block_scout_web/test/block_scout_web/controllers/smart_contract_controller_test.exs
  9. 2
      apps/block_scout_web/test/block_scout_web/controllers/tokens/read_contract_controller_test.exs
  10. 2
      apps/block_scout_web/test/block_scout_web/schema/query/address_test.exs
  11. 2
      apps/block_scout_web/test/block_scout_web/schema/query/addresses_test.exs
  12. 8
      apps/block_scout_web/test/block_scout_web/views/address_view_test.exs
  13. 6
      apps/block_scout_web/test/block_scout_web/views/tokens/overview_view_test.exs
  14. 14
      apps/explorer/lib/explorer/chain.ex
  15. 23
      apps/explorer/lib/explorer/chain/smart_contract.ex
  16. 35
      apps/explorer/lib/explorer/smart_contract/helper.ex
  17. 23
      apps/explorer/priv/repo/migrations/20220303083252_smart_contracts_contract_code_md5.exs
  18. 3
      apps/explorer/test/explorer/chain/log_test.exs
  19. 2
      apps/explorer/test/explorer/chain/transaction_test.exs
  20. 42
      apps/explorer/test/explorer/chain_test.exs
  21. 10
      apps/explorer/test/explorer/smart_contract/reader_test.exs
  22. 6
      apps/explorer/test/explorer/smart_contract/writer_test.exs
  23. 8
      apps/explorer/test/support/factory.ex

@ -9,6 +9,7 @@
- [#4690](https://github.com/blockscout/blockscout/pull/4690) - Improve pagination: introduce pagination with random access to pages; Integrate it to the Transactions List page
### Fixes
- [#5248](https://github.com/blockscout/blockscout/pull/5248) - Speedup query for getting verified smart-contract bytecode twin
- [#5241](https://github.com/blockscout/blockscout/pull/5241) - Fix DB hostname Regex pattern
- [#5216](https://github.com/blockscout/blockscout/pull/5216) - Add token-transfers-toggle.js to the `block_transaction/index.html.eex`
- [#5212](https://github.com/blockscout/blockscout/pull/5212) - Fix `gas_used` value bug

@ -50,7 +50,7 @@ defmodule BlockScoutWeb.AddressReadContractControllerTest do
block_index: 0
)
insert(:smart_contract, address_hash: contract_address.hash)
insert(:smart_contract, address_hash: contract_address.hash, contract_code_md5: "123")
get_eip1967_implementation()

@ -49,7 +49,7 @@ defmodule BlockScoutWeb.AddressReadProxyControllerTest do
block_index: 0
)
insert(:smart_contract, address_hash: contract_address.hash)
insert(:smart_contract, address_hash: contract_address.hash, contract_code_md5: "123")
get_eip1967_implementation()

@ -51,7 +51,7 @@ defmodule BlockScoutWeb.AddressWriteContractControllerTest do
block_index: 0
)
insert(:smart_contract, address_hash: contract_address.hash)
insert(:smart_contract, address_hash: contract_address.hash, contract_code_md5: "123")
get_eip1967_implementation()

@ -49,7 +49,7 @@ defmodule BlockScoutWeb.AddressWriteProxyControllerTest do
block_index: 0
)
insert(:smart_contract, address_hash: contract_address.hash)
insert(:smart_contract, address_hash: contract_address.hash, contract_code_md5: "123")
get_eip1967_implementation()

@ -36,7 +36,7 @@ defmodule BlockScoutWeb.API.RPC.ContractControllerTest do
end
test "with a verified smart contract, all contract information is shown", %{conn: conn, params: params} do
contract = insert(:smart_contract)
contract = insert(:smart_contract, contract_code_md5: "123")
response =
conn
@ -82,7 +82,7 @@ defmodule BlockScoutWeb.API.RPC.ContractControllerTest do
test "filtering for only unverified contracts shows only unverified contracts", %{params: params, conn: conn} do
address = insert(:contract_address)
insert(:smart_contract)
insert(:smart_contract, contract_code_md5: "123")
response =
conn
@ -107,7 +107,7 @@ defmodule BlockScoutWeb.API.RPC.ContractControllerTest do
conn: conn
} do
address = insert(:contract_address)
insert(:smart_contract)
insert(:smart_contract, contract_code_md5: "123")
insert(:contract_address, contract_code: "0x")
response =
@ -130,7 +130,7 @@ defmodule BlockScoutWeb.API.RPC.ContractControllerTest do
test "filtering for only verified contracts shows only verified contracts", %{params: params, conn: conn} do
insert(:contract_address)
contract = insert(:smart_contract)
contract = insert(:smart_contract, contract_code_md5: "123")
response =
conn
@ -222,7 +222,7 @@ defmodule BlockScoutWeb.API.RPC.ContractControllerTest do
test "filtering for only not_decompiled (and by extension not verified contracts)", %{params: params, conn: conn} do
insert(:decompiled_smart_contract)
insert(:smart_contract)
insert(:smart_contract, contract_code_md5: "123")
contract_address = insert(:contract_address)
response =
@ -248,7 +248,7 @@ defmodule BlockScoutWeb.API.RPC.ContractControllerTest do
conn: conn
} do
insert(:decompiled_smart_contract)
insert(:smart_contract)
insert(:smart_contract, contract_code_md5: "123")
insert(:contract_address, contract_code: "0x")
contract_address = insert(:contract_address)
@ -328,7 +328,7 @@ defmodule BlockScoutWeb.API.RPC.ContractControllerTest do
end
test "with a verified contract address", %{conn: conn} do
contract = insert(:smart_contract)
contract = insert(:smart_contract, contract_code_md5: "123")
params = %{
"module" => "contract",
@ -424,7 +424,13 @@ defmodule BlockScoutWeb.API.RPC.ContractControllerTest do
end
test "with a verified contract address", %{conn: conn} do
contract = insert(:smart_contract, optimization: true, optimization_runs: 200, evm_version: "default")
contract =
insert(:smart_contract,
optimization: true,
optimization_runs: 200,
evm_version: "default",
contract_code_md5: "123"
)
params = %{
"module" => "contract",
@ -470,7 +476,8 @@ defmodule BlockScoutWeb.API.RPC.ContractControllerTest do
optimization_runs: 200,
evm_version: "default",
constructor_arguments:
"00000000000000000000000008e7592ce0d7ebabf42844b62ee6a878d4e1913e000000000000000000000000e1b6037da5f1d756499e184ca15254a981c92546"
"00000000000000000000000008e7592ce0d7ebabf42844b62ee6a878d4e1913e000000000000000000000000e1b6037da5f1d756499e184ca15254a981c92546",
contract_code_md5: "123"
)
params = %{

@ -94,7 +94,7 @@ defmodule BlockScoutWeb.ChainControllerTest do
end
test "finds verified contract" do
insert(:smart_contract, name: "SuperToken")
insert(:smart_contract, name: "SuperToken", contract_code_md5: "123")
conn =
build_conn()
@ -104,7 +104,7 @@ defmodule BlockScoutWeb.ChainControllerTest do
end
test "finds verified contract and token" do
insert(:smart_contract, name: "MagicContract")
insert(:smart_contract, name: "MagicContract", contract_code_md5: "123")
insert(:token, name: "magicToken")
conn =
@ -115,10 +115,10 @@ defmodule BlockScoutWeb.ChainControllerTest do
end
test "finds verified contracts and tokens" do
insert(:smart_contract, name: "something")
insert(:smart_contract, name: "MagicContract")
insert(:smart_contract, name: "something", contract_code_md5: "123")
insert(:smart_contract, name: "MagicContract", contract_code_md5: "123")
insert(:token, name: "Magic3")
insert(:smart_contract, name: "magicContract2")
insert(:smart_contract, name: "magicContract2", contract_code_md5: "123")
insert(:token, name: "magicToken")
insert(:token, name: "OneMoreToken")
@ -142,7 +142,7 @@ defmodule BlockScoutWeb.ChainControllerTest do
test "find by empty query" do
insert(:token, name: "MaGiCt0k3n")
insert(:smart_contract, name: "MagicContract")
insert(:smart_contract, name: "MagicContract", contract_code_md5: "123")
conn =
build_conn()

@ -33,7 +33,7 @@ defmodule BlockScoutWeb.SmartContractControllerTest do
end
test "only responds to ajax requests", %{conn: conn} do
smart_contract = insert(:smart_contract)
smart_contract = insert(:smart_contract, contract_code_md5: "123")
path = smart_contract_path(BlockScoutWeb.Endpoint, :index, hash: smart_contract.address_hash)
@ -45,7 +45,7 @@ defmodule BlockScoutWeb.SmartContractControllerTest do
test "lists the smart contract read only functions" do
token_contract_address = insert(:contract_address)
insert(:smart_contract, address_hash: token_contract_address.hash)
insert(:smart_contract, address_hash: token_contract_address.hash, contract_code_md5: "123")
blockchain_get_code_mock()
blockchain_get_function_mock()
@ -81,7 +81,8 @@ defmodule BlockScoutWeb.SmartContractControllerTest do
"inputs" => [],
"constant" => true
}
]
],
contract_code_md5: "123"
)
blockchain_get_code_mock()
@ -117,7 +118,8 @@ defmodule BlockScoutWeb.SmartContractControllerTest do
"inputs" => [],
"constant" => false
}
]
],
contract_code_md5: "123"
)
blockchain_get_code_mock()
@ -154,7 +156,8 @@ defmodule BlockScoutWeb.SmartContractControllerTest do
"inputs" => [],
"constant" => false
}
]
],
contract_code_md5: "123"
)
blockchain_get_code_mock()
@ -217,7 +220,7 @@ defmodule BlockScoutWeb.SmartContractControllerTest do
end
test "only responds to ajax requests", %{conn: conn} do
smart_contract = insert(:smart_contract)
smart_contract = insert(:smart_contract, contract_code_md5: "123")
path =
smart_contract_path(
@ -235,7 +238,7 @@ defmodule BlockScoutWeb.SmartContractControllerTest do
test "fetch the function value from the blockchain" do
address = insert(:contract_address)
smart_contract = insert(:smart_contract, address_hash: address.hash)
smart_contract = insert(:smart_contract, address_hash: address.hash, contract_code_md5: "123")
blockchain_get_code_mock()
blockchain_get_function_mock()

@ -36,7 +36,7 @@ defmodule BlockScoutWeb.Tokens.ContractControllerTest do
test "successfully renders the page when the token is a verified smart contract", %{conn: conn} do
token_contract_address = insert(:contract_address)
insert(:smart_contract, address_hash: token_contract_address.hash)
insert(:smart_contract, address_hash: token_contract_address.hash, contract_code_md5: "123")
token = insert(:token, contract_address: token_contract_address)

@ -58,7 +58,7 @@ defmodule BlockScoutWeb.Schema.Query.AddressTest do
test "smart_contract returns all expected fields", %{conn: conn} do
address = insert(:address, fetched_coin_balance: 100)
smart_contract = insert(:smart_contract, address_hash: address.hash)
smart_contract = insert(:smart_contract, address_hash: address.hash, contract_code_md5: "123")
query = """
query ($hash: AddressHash!) {

@ -62,7 +62,7 @@ defmodule BlockScoutWeb.Schema.Query.AddressesTest do
test "smart_contract returns all expected fields", %{conn: conn} do
address = insert(:address, fetched_coin_balance: 100)
smart_contract = insert(:smart_contract, address_hash: address.hash)
smart_contract = insert(:smart_contract, address_hash: address.hash, contract_code_md5: "123")
query = """
query ($hashes: [AddressHash!]!) {

@ -235,7 +235,7 @@ defmodule BlockScoutWeb.AddressViewTest do
describe "smart_contract_verified?/1" do
test "returns true when smart contract is verified" do
smart_contract = insert(:smart_contract)
smart_contract = insert(:smart_contract, contract_code_md5: "123")
address = insert(:address, smart_contract: smart_contract)
assert AddressView.smart_contract_verified?(address)
@ -263,7 +263,8 @@ defmodule BlockScoutWeb.AddressViewTest do
"stateMutability" => "view",
"type" => "function"
}
]
],
contract_code_md5: "123"
)
address = insert(:address, smart_contract: smart_contract)
@ -285,7 +286,8 @@ defmodule BlockScoutWeb.AddressViewTest do
"stateMutability" => "nonpayable",
"type" => "function"
}
]
],
contract_code_md5: "123"
)
address = insert(:address, smart_contract: smart_contract)

@ -94,7 +94,8 @@ defmodule BlockScoutWeb.Tokens.OverviewViewTest do
"stateMutability" => "view",
"type" => "function"
}
]
],
contract_code_md5: "123"
)
address = insert(:address, smart_contract: smart_contract)
@ -118,7 +119,8 @@ defmodule BlockScoutWeb.Tokens.OverviewViewTest do
"stateMutability" => "nonpayable",
"type" => "function"
}
]
],
contract_code_md5: "123"
)
address = insert(:address, smart_contract: smart_contract)

@ -83,7 +83,7 @@ defmodule Explorer.Chain do
alias Explorer.Counters.{AddressesCounter, AddressesWithBalanceCounter}
alias Explorer.Market.MarketHistoryCache
alias Explorer.{PagingOptions, Repo}
alias Explorer.SmartContract.Reader
alias Explorer.SmartContract.{Helper, Reader}
alias Explorer.Staking.ContractState
alias Dataloader.Ecto, as: DataloaderEcto
@ -3965,6 +3965,10 @@ defmodule Explorer.Chain do
def create_smart_contract(attrs \\ %{}, external_libraries \\ [], secondary_sources \\ []) do
new_contract = %SmartContract{}
attrs =
attrs
|> Helper.add_contract_code_md5()
smart_contract_changeset =
new_contract
|> SmartContract.changeset(attrs)
@ -4172,11 +4176,9 @@ defmodule Explorer.Chain do
verified_contract_twin_query =
from(
address in Address,
inner_join: smart_contract in SmartContract,
on: address.hash == smart_contract.address_hash,
where: fragment("md5(contract_code::text)") == ^contract_code_md5,
where: address.hash != ^target_address_hash,
smart_contract in SmartContract,
where: smart_contract.contract_code_md5 == ^contract_code_md5,
where: smart_contract.address_hash != ^target_address_hash,
select: smart_contract,
limit: 1
)

@ -198,6 +198,7 @@ defmodule Explorer.Chain.SmartContract do
* `file_path` - show the filename or path to the file of the contract source file
* `is_changed_bytecode` - boolean flag, determines if contract's bytecode was modified
* `bytecode_checked_at` - timestamp of the last check of contract's bytecode matching (DB and BlockChain)
* `contract_code_md5` - md5(`t:Explorer.Chain.Address.t/0` `contract_code`)
"""
@type t :: %Explorer.Chain.SmartContract{
@ -214,7 +215,8 @@ defmodule Explorer.Chain.SmartContract do
file_path: String.t(),
is_vyper_contract: boolean | nil,
is_changed_bytecode: boolean,
bytecode_checked_at: DateTime.t()
bytecode_checked_at: DateTime.t(),
contract_code_md5: String.t()
}
schema "smart_contracts" do
@ -233,6 +235,7 @@ defmodule Explorer.Chain.SmartContract do
field(:is_vyper_contract, :boolean)
field(:is_changed_bytecode, :boolean, default: false)
field(:bytecode_checked_at, :utc_datetime_usec, default: DateTime.add(DateTime.utc_now(), -86400, :second))
field(:contract_code_md5, :string)
has_many(
:decompiled_smart_contracts,
@ -272,9 +275,18 @@ defmodule Explorer.Chain.SmartContract do
:file_path,
:is_vyper_contract,
:is_changed_bytecode,
:bytecode_checked_at
:bytecode_checked_at,
:contract_code_md5
])
|> validate_required([
:name,
:compiler_version,
:optimization,
:contract_source_code,
:abi,
:address_hash,
:contract_code_md5
])
|> validate_required([:name, :compiler_version, :optimization, :contract_source_code, :abi, :address_hash])
|> unique_constraint(:address_hash)
|> prepare_changes(&upsert_contract_methods/1)
end
@ -302,11 +314,12 @@ defmodule Explorer.Chain.SmartContract do
:file_path,
:is_vyper_contract,
:is_changed_bytecode,
:bytecode_checked_at
:bytecode_checked_at,
:contract_code_md5
])
|> (&if(json_verification,
do: &1,
else: validate_required(&1, [:name, :compiler_version, :optimization, :address_hash])
else: validate_required(&1, [:name, :compiler_version, :optimization, :address_hash, :contract_code_md5])
)).()
field_to_put_message = if json_verification, do: :file, else: :contract_source_code

@ -3,6 +3,8 @@ defmodule Explorer.SmartContract.Helper do
SmartContract helper functions
"""
alias Explorer.Chain
def queriable_method?(method) do
method["constant"] || method["stateMutability"] == "view" || method["stateMutability"] == "pure"
end
@ -36,4 +38,37 @@ defmodule Explorer.SmartContract.Helper do
false
end
end
def add_contract_code_md5(%{address_hash: address_hash_string} = attrs) when is_binary(address_hash_string) do
with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string),
{:ok, address} <- Chain.hash_to_address(address_hash) do
contract_code_md5 =
:md5
|> :crypto.hash(address.contract_code.bytes)
|> Base.encode16(case: :lower)
attrs
|> Map.put_new(:contract_code_md5, contract_code_md5)
else
_ -> attrs
end
end
def add_contract_code_md5(%{address_hash: address_hash} = attrs) do
case Chain.hash_to_address(address_hash) do
{:ok, address} ->
contract_code_md5 =
:md5
|> :crypto.hash(address.contract_code.bytes)
|> Base.encode16(case: :lower)
attrs
|> Map.put_new(:contract_code_md5, contract_code_md5)
_ ->
attrs
end
end
def add_contract_code_md5(attrs), do: attrs
end

@ -0,0 +1,23 @@
defmodule Explorer.Repo.Migrations.SmartContractsContractCodeMd5 do
use Ecto.Migration
def change do
alter table(:smart_contracts) do
add(:contract_code_md5, :string, null: true)
end
execute("""
UPDATE smart_contracts
SET contract_code_md5 = md5(a.contract_code)
FROM addresses a
WHERE smart_contracts.address_hash = a.hash;
""")
alter table(:smart_contracts) do
modify(:contract_code_md5, :string, null: false)
end
drop_if_exists(index(:addresses, ["md5(contract_code::text)"], name: "addresses_contract_code_index"))
create(index(:smart_contracts, :contract_code_md5))
end
end

@ -75,7 +75,8 @@ defmodule Explorer.Chain.LogTest do
"type" => "event"
}
],
address_hash: to_address.hash
address_hash: to_address.hash,
contract_code_md5: "123"
)
topic1_bytes = ExKeccak.hash_256("WantsPets(string,uint256,bool)")

@ -305,7 +305,7 @@ defmodule Explorer.Chain.TransactionTest do
|> insert()
|> Repo.preload(to_address: :smart_contract)
contract = insert(:smart_contract) |> Repo.preload(:address)
contract = insert(:smart_contract, contract_code_md5: "123") |> Repo.preload(:address)
input_data =
"set(uint)"

@ -4403,7 +4403,7 @@ defmodule Explorer.ChainTest do
describe "address_hash_to_smart_contract/1" do
test "fetches a smart contract" do
smart_contract = insert(:smart_contract)
smart_contract = insert(:smart_contract, contract_code_md5: "123")
assert ^smart_contract = Chain.address_hash_to_smart_contract(smart_contract.address_hash)
end
@ -5646,16 +5646,21 @@ defmodule Explorer.ChainTest do
test "combine_proxy_implementation_abi/2 returns proxy abi if implementation is not verified" do
proxy_contract_address = insert(:contract_address)
insert(:smart_contract, address_hash: proxy_contract_address.hash, abi: @proxy_abi)
insert(:smart_contract, address_hash: proxy_contract_address.hash, abi: @proxy_abi, contract_code_md5: "123")
assert Chain.combine_proxy_implementation_abi(proxy_contract_address, @proxy_abi) == @proxy_abi
end
test "combine_proxy_implementation_abi/2 returns proxy + implementation abi if implementation is verified" do
proxy_contract_address = insert(:contract_address)
insert(:smart_contract, address_hash: proxy_contract_address.hash, abi: @proxy_abi)
insert(:smart_contract, address_hash: proxy_contract_address.hash, abi: @proxy_abi, contract_code_md5: "123")
implementation_contract_address = insert(:contract_address)
insert(:smart_contract, address_hash: implementation_contract_address.hash, abi: @implementation_abi)
insert(:smart_contract,
address_hash: implementation_contract_address.hash,
abi: @implementation_abi,
contract_code_md5: "123"
)
implementation_contract_address_hash_string =
Base.encode16(implementation_contract_address.hash.bytes, case: :lower)
@ -5728,16 +5733,21 @@ defmodule Explorer.ChainTest do
test "get_implementation_abi_from_proxy/2 returns [] if implementation is not verified" do
proxy_contract_address = insert(:contract_address)
insert(:smart_contract, address_hash: proxy_contract_address.hash, abi: @proxy_abi)
insert(:smart_contract, address_hash: proxy_contract_address.hash, abi: @proxy_abi, contract_code_md5: "123")
assert Chain.get_implementation_abi_from_proxy(proxy_contract_address, @proxy_abi) == []
end
test "get_implementation_abi_from_proxy/2 returns implementation abi if implementation is verified" do
proxy_contract_address = insert(:contract_address)
insert(:smart_contract, address_hash: proxy_contract_address.hash, abi: @proxy_abi)
insert(:smart_contract, address_hash: proxy_contract_address.hash, abi: @proxy_abi, contract_code_md5: "123")
implementation_contract_address = insert(:contract_address)
insert(:smart_contract, address_hash: implementation_contract_address.hash, abi: @implementation_abi)
insert(:smart_contract,
address_hash: implementation_contract_address.hash,
abi: @implementation_abi,
contract_code_md5: "123"
)
implementation_contract_address_hash_string =
Base.encode16(implementation_contract_address.hash.bytes, case: :lower)
@ -5764,10 +5774,15 @@ defmodule Explorer.ChainTest do
test "get_implementation_abi_from_proxy/2 returns implementation abi in case of EIP-1967 proxy pattern" do
proxy_contract_address = insert(:contract_address)
insert(:smart_contract, address_hash: proxy_contract_address.hash, abi: [])
insert(:smart_contract, address_hash: proxy_contract_address.hash, abi: [], contract_code_md5: "123")
implementation_contract_address = insert(:contract_address)
insert(:smart_contract, address_hash: implementation_contract_address.hash, abi: @implementation_abi)
insert(:smart_contract,
address_hash: implementation_contract_address.hash,
abi: @implementation_abi,
contract_code_md5: "123"
)
implementation_contract_address_hash_string =
Base.encode16(implementation_contract_address.hash.bytes, case: :lower)
@ -5809,10 +5824,15 @@ defmodule Explorer.ChainTest do
test "get_implementation_abi/1 returns implementation abi if implementation is verified" do
proxy_contract_address = insert(:contract_address)
insert(:smart_contract, address_hash: proxy_contract_address.hash, abi: @proxy_abi)
insert(:smart_contract, address_hash: proxy_contract_address.hash, abi: @proxy_abi, contract_code_md5: "123")
implementation_contract_address = insert(:contract_address)
insert(:smart_contract, address_hash: implementation_contract_address.hash, abi: @implementation_abi)
insert(:smart_contract,
address_hash: implementation_contract_address.hash,
abi: @implementation_abi,
contract_code_md5: "123"
)
implementation_contract_address_hash_string =
Base.encode16(implementation_contract_address.hash.bytes, case: :lower)

@ -190,7 +190,8 @@ defmodule Explorer.SmartContract.ReaderTest do
"inputs" => [],
"constant" => true
}
]
],
contract_code_md5: "123"
)
implementation_contract_address = insert(:contract_address)
@ -216,7 +217,8 @@ defmodule Explorer.SmartContract.ReaderTest do
"stateMutability" => "view",
"type" => "function"
}
]
],
contract_code_md5: "123"
)
implementation_contract_address_hash_string =
@ -255,7 +257,7 @@ defmodule Explorer.SmartContract.ReaderTest do
describe "query_function/3" do
test "given the arguments, fetches the function value from the blockchain" do
smart_contract = insert(:smart_contract)
smart_contract = insert(:smart_contract, contract_code_md5: "123")
blockchain_get_function_mock()
@ -268,7 +270,7 @@ defmodule Explorer.SmartContract.ReaderTest do
end
test "nil arguments is treated as []" do
smart_contract = insert(:smart_contract)
smart_contract = insert(:smart_contract, contract_code_md5: "123")
blockchain_get_function_mock()

@ -283,14 +283,16 @@ defmodule Explorer.SmartContract.WriterTest do
test "fetches the smart contract proxy write functions" do
_proxy_smart_contract =
insert(:smart_contract,
abi: @abi
abi: @abi,
contract_code_md5: "123"
)
implementation_contract_address = insert(:contract_address)
insert(:smart_contract,
address_hash: implementation_contract_address.hash,
abi: @implementation_abi
abi: @implementation_abi,
contract_code_md5: "123"
)
implementation_contract_address_hash_string =

@ -607,13 +607,19 @@ defmodule Explorer.Factory do
def smart_contract_factory do
contract_code_info = contract_code_info()
bytecode_md5 =
:md5
|> :crypto.hash(contract_code_info.bytecode)
|> Base.encode16(case: :lower)
%SmartContract{
address_hash: insert(:address, contract_code: contract_code_info.bytecode, verified: true).hash,
compiler_version: contract_code_info.version,
name: contract_code_info.name,
contract_source_code: contract_code_info.source_code,
optimization: contract_code_info.optimized,
abi: contract_code_info.abi
abi: contract_code_info.abi,
contract_code_md5: bytecode_md5
}
end

Loading…
Cancel
Save