diff --git a/apps/explorer/lib/explorer/chain.ex b/apps/explorer/lib/explorer/chain.ex index 293aa3fa34..29434c2414 100644 --- a/apps/explorer/lib/explorer/chain.ex +++ b/apps/explorer/lib/explorer/chain.ex @@ -1868,6 +1868,32 @@ defmodule Explorer.Chain do |> Data.to_string() end + @doc """ + Fetches contract creation input data. + """ + @spec contract_creation_input_data(String.t()) :: nil | String.t() + def contract_creation_input_data(address_hash) do + query = + from( + address in Address, + where: address.hash == ^address_hash, + preload: [:contracts_creation_internal_transaction, :contracts_creation_transaction] + ) + + transaction = Repo.one(query) + + cond do + is_nil(transaction) -> + nil + + !is_nil(transaction.contracts_creation_internal_transaction) -> + Data.to_string(transaction.contracts_creation_internal_transaction.input) + + !is_nil(transaction.contracts_creation_transaction) -> + Data.to_string(transaction.contracts_creation_transaction.input) + end + end + @doc """ Inserts a `t:SmartContract.t/0`. diff --git a/apps/explorer/test/explorer/chain_test.exs b/apps/explorer/test/explorer/chain_test.exs index 13bd3ef766..6fef5835ff 100644 --- a/apps/explorer/test/explorer/chain_test.exs +++ b/apps/explorer/test/explorer/chain_test.exs @@ -3557,4 +3557,58 @@ defmodule Explorer.ChainTest do assert Chain.block_combined_rewards(block) == expected_value end end + + describe "contract_creation_input_data/1" do + test "fetches contract creation input data from contract creation transaction" do + address = insert(:address) + + input = %Data{ + bytes: <<1, 2, 3, 4, 5>> + } + + :transaction + |> insert(created_contract_address_hash: address.hash, input: input) + |> with_block() + + found_creation_data = Chain.contract_creation_input_data(address.hash) + + assert found_creation_data == Data.to_string(input) + end + + test "fetches contract creation input data from internal transaction" do + created_contract_address = insert(:address) + + transaction = + :transaction + |> insert() + |> with_block() + + input = %Data{ + bytes: <<1, 2, 3, 4, 5>> + } + + insert( + :internal_transaction_create, + transaction: transaction, + index: 0, + created_contract_address: created_contract_address, + block_number: transaction.block_number, + transaction_index: transaction.index, + input: input + ) + + assert Chain.contract_creation_input_data(created_contract_address.hash) == Data.to_string(input) + end + + test "can't find address" do + hash = %Hash{ + byte_count: 20, + bytes: <<0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0>> + } + + found_creation_data = Chain.contract_creation_input_data(hash) + + assert is_nil(found_creation_data) + end + end end