Merge branch 'master' into vb-extend-contract-api-view

pull/2857/head
Victor Baranov 5 years ago committed by GitHub
commit 723106e091
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 5
      CHANGELOG.md
  2. 2
      apps/block_scout_web/README.md
  3. 8
      apps/block_scout_web/assets/js/pages/verification_form.js
  4. 21
      apps/block_scout_web/lib/block_scout_web/templates/address_contract_verification/new.html.eex
  5. 34
      apps/block_scout_web/priv/gettext/default.pot
  6. 34
      apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po
  7. 6
      apps/explorer/lib/explorer/smart_contract/publisher.ex
  8. 26
      apps/explorer/lib/explorer/smart_contract/verifier.ex
  9. 68
      apps/explorer/lib/explorer/smart_contract/verifier/constructor_arguments.ex
  10. 6
      apps/explorer/lib/explorer/token/instance_metadata_retriever.ex
  11. 32
      apps/explorer/test/explorer/smart_contract/publisher_test.exs
  12. 84
      apps/explorer/test/explorer/smart_contract/verifier/constructor_arguments_test.exs

@ -3,13 +3,16 @@
### Features
- [#2862](https://github.com/poanetwork/blockscout/pull/2862) - Coin total supply from DB API endpoint
- [#2857](https://github.com/poanetwork/blockscout/pull/2857) - Extend getsourcecode API view with new output fields
- [#2822](https://github.com/poanetwork/blockscout/pull/2822) - Estimated address count on the main page, if cache is empty
- [#2821](https://github.com/poanetwork/blockscout/pull/2821) - add autodetection of constructor arguments
- [#2825](https://github.com/poanetwork/blockscout/pull/2825) - separate token transfers and transactions
- [#2787](https://github.com/poanetwork/blockscout/pull/2787) - async fetching of address counters
- [#2791](https://github.com/poanetwork/blockscout/pull/2791) - add ipc client
- [#2449](https://github.com/poanetwork/blockscout/pull/2449) - add ability to send notification events through postgres notify
- [#2822](https://github.com/poanetwork/blockscout/pull/2822) - Estimated address count on the main page, if cache is empty
### Fixes
- [#2864](https://github.com/poanetwork/blockscout/pull/2864) - add token instance metadata type check
- [#2855](https://github.com/poanetwork/blockscout/pull/2855) - Fix favicons load
- [#2854](https://github.com/poanetwork/blockscout/pull/2854) - Fix all npm vulnerabilities
- [#2851](https://github.com/poanetwork/blockscout/pull/2851) - Fix paths for front assets

@ -21,7 +21,7 @@ This is a tool for inspecting and analyzing the POA Network blockchain from a we
To get BlockScout Web interface up and running locally:
* Setup `../explorer`
* Set up some default configuration with: `$ cp config/dev.secret.exs.example config/dev.secret.esx`
* Set up some default configuration with: `$ cp config/dev.secret.exs.example config/dev.secret.exs`
* Install Node.js dependencies with `$ cd assets && npm install && cd ..`
* Start Phoenix with `$ mix phx.server` (This can be run from this directory or the project root: the project root is recommended.)

@ -121,6 +121,14 @@ if ($contractVerificationPage.length) {
$(this).hide()
})
$('.autodetectfalse').on('click', function () {
if ($(this).prop('checked')) { $('.constructor-arguments').show() }
})
$('.autodetecttrue').on('click', function () {
if ($(this).prop('checked')) { $('.constructor-arguments').hide() }
})
$('.js-smart-contract-form-reset').on('click', function () {
$('.js-contract-library-form-group').removeClass('active')
$('.js-contract-library-form-group').first().addClass('active')

@ -100,6 +100,27 @@
</div>
<div class="smart-contract-form-group">
<div class="smart-contract-form-group-inner-wrapper">
<%= label f, "Try to fetch contructor arguments automatically" %>
<div class="center-column">
<div class="form-radios-group">
<div class="radio-big">
<%= radio_button f, :autodetect_contructor_args, false, checked: true, class: "form-check-input autodetectfalse" %>
<div class="radio-icon"></div>
<%= label :autodetect_contructor_args, :false, gettext("No"), class: "radio-text" %>
</div>
<div class="radio-big">
<%= radio_button f, :autodetect_contructor_args, true, class: "form-check-input autodetecttrue", "aria-describedby": "optimization-help-block" %>
<div class="radio-icon"></div>
<%= label :autodetect_contructor_args, :true, gettext("Yes"), class: "radio-text" %>
</div>
</div>
<%= error_tag f, :autodetect_contructor_args, id: "optimization-help-block", class: "text-danger form-error" %>
</div>
</div>
</div>
<div class="smart-contract-form-group constructor-arguments">
<div class="smart-contract-form-group-inner-wrapper">
<%= label f, :contructor_arguments, gettext("ABI-encoded Constructor Arguments (if required by the contract)") %>
<div class="center-column">

@ -87,7 +87,7 @@ msgid "A string with the name of the module to be invoked."
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:104
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:125
msgid "ABI-encoded Constructor Arguments (if required by the contract)"
msgstr ""
@ -266,7 +266,7 @@ msgid "Call Code"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:253
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:274
#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:47
#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:54
msgid "Cancel"
@ -370,7 +370,7 @@ msgid "Contract Creation Code"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:118
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:139
msgid "Contract Libraries"
msgstr ""
@ -971,20 +971,20 @@ msgid "Less than"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:133
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:155
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:177
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:199
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:221
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:154
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:176
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:198
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:220
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:242
msgid "Library Address"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:123
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:145
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:167
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:189
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:211
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:144
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:166
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:188
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:210
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:232
msgid "Library Name"
msgstr ""
@ -1010,7 +1010,7 @@ msgid "Loading..."
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:247
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:268
msgid "Loading...."
msgstr ""
@ -1097,6 +1097,7 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:67
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:110
msgid "No"
msgstr ""
@ -1217,7 +1218,7 @@ msgid "Request URL"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:250
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:271
msgid "Reset"
msgstr ""
@ -1579,7 +1580,7 @@ msgid "Verify & Publish"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:249
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:270
msgid "Verify & publish"
msgstr ""
@ -1654,6 +1655,7 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:72
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:115
msgid "Yes"
msgstr ""

@ -87,7 +87,7 @@ msgid "A string with the name of the module to be invoked."
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:104
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:125
msgid "ABI-encoded Constructor Arguments (if required by the contract)"
msgstr ""
@ -266,7 +266,7 @@ msgid "Call Code"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:253
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:274
#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:47
#: lib/block_scout_web/templates/api_docs/_eth_rpc_item.html.eex:54
msgid "Cancel"
@ -370,7 +370,7 @@ msgid "Contract Creation Code"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:118
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:139
msgid "Contract Libraries"
msgstr ""
@ -971,20 +971,20 @@ msgid "Less than"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:133
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:155
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:177
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:199
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:221
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:154
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:176
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:198
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:220
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:242
msgid "Library Address"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:123
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:145
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:167
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:189
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:211
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:144
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:166
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:188
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:210
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:232
msgid "Library Name"
msgstr ""
@ -1010,7 +1010,7 @@ msgid "Loading..."
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:247
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:268
msgid "Loading...."
msgstr ""
@ -1097,6 +1097,7 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:67
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:110
msgid "No"
msgstr ""
@ -1217,7 +1218,7 @@ msgid "Request URL"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:250
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:271
msgid "Reset"
msgstr ""
@ -1579,7 +1580,7 @@ msgid "Verify & Publish"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:249
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:270
msgid "Verify & publish"
msgstr ""
@ -1654,6 +1655,7 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:72
#: lib/block_scout_web/templates/address_contract_verification/new.html.eex:115
msgid "Yes"
msgstr ""

@ -27,6 +27,12 @@ defmodule Explorer.SmartContract.Publisher do
params_with_external_libaries = add_external_libraries(params, external_libraries)
case Verifier.evaluate_authenticity(address_hash, params_with_external_libaries) do
{:ok, %{abi: abi, contructor_arguments: contructor_arguments}} ->
params_with_contructor_arguments =
Map.put(params_with_external_libaries, "constructor_arguments", contructor_arguments)
publish_smart_contract(address_hash, params_with_contructor_arguments, abi)
{:ok, %{abi: abi}} ->
publish_smart_contract(address_hash, params_with_external_libaries, abi)

@ -41,6 +41,7 @@ defmodule Explorer.SmartContract.Verifier do
constructor_arguments = Map.get(params, "constructor_arguments", "")
evm_version = Map.get(params, "evm_version")
optimization_runs = Map.get(params, "optimization_runs", 200)
autodetect_contructor_arguments = params |> Map.get("autodetect_contructor_args", "false") |> parse_boolean()
solc_output =
CodeCompiler.run(
@ -53,13 +54,18 @@ defmodule Explorer.SmartContract.Verifier do
external_libs: external_libraries
)
compare_bytecodes(solc_output, address_hash, constructor_arguments)
compare_bytecodes(solc_output, address_hash, constructor_arguments, autodetect_contructor_arguments)
end
defp compare_bytecodes({:error, :name}, _, _), do: {:error, :name}
defp compare_bytecodes({:error, _}, _, _), do: {:error, :compilation}
defp compare_bytecodes({:error, :name}, _, _, _), do: {:error, :name}
defp compare_bytecodes({:error, _}, _, _, _), do: {:error, :compilation}
defp compare_bytecodes({:ok, %{"abi" => abi, "bytecode" => bytecode}}, address_hash, arguments_data) do
defp compare_bytecodes(
{:ok, %{"abi" => abi, "bytecode" => bytecode}},
address_hash,
arguments_data,
autodetect_contructor_arguments
) do
generated_bytecode = extract_bytecode(bytecode)
"0x" <> blockchain_bytecode =
@ -73,6 +79,15 @@ defmodule Explorer.SmartContract.Verifier do
!try_library_verification(generated_bytecode, blockchain_bytecode_without_whisper) ->
{:error, :generated_bytecode}
has_constructor_with_params?(abi) && autodetect_contructor_arguments ->
result = ConstructorArguments.find_constructor_arguments(address_hash, abi)
if result do
{:ok, %{abi: abi, contructor_arguments: result}}
else
{:error, :constructor_arguments}
end
has_constructor_with_params?(abi) &&
!ConstructorArguments.verify(address_hash, blockchain_bytecode_without_whisper, arguments_data) ->
{:error, :constructor_arguments}
@ -162,4 +177,7 @@ defmodule Explorer.SmartContract.Verifier do
defp has_constructor_with_params?(abi) do
Enum.any?(abi, fn el -> el["type"] == "constructor" && el["inputs"] != [] end)
end
defp parse_boolean("true"), do: true
defp parse_boolean("false"), do: false
end

@ -2,7 +2,7 @@ defmodule Explorer.SmartContract.Verifier.ConstructorArguments do
@moduledoc """
Smart contract contrstructor arguments verification logic.
"""
alias ABI.{FunctionSelector, TypeDecoder}
alias Explorer.Chain
def verify(address_hash, contract_code, arguments_data) do
@ -13,56 +13,90 @@ defmodule Explorer.SmartContract.Verifier.ConstructorArguments do
|> Chain.contract_creation_input_data()
|> String.replace("0x", "")
if verify_older_version(creation_code, contract_code, arguments_data) do
check_func = fn assumed_arguments -> assumed_arguments == arguments_data end
if verify_older_version(creation_code, contract_code, check_func) do
true
else
extract_constructor_arguments(creation_code, arguments_data)
extract_constructor_arguments(creation_code, check_func)
end
end
# Earlier versions of Solidity didn't have whisper code.
# constructor argument were directly appended to source code
defp verify_older_version(creation_code, contract_code, arguments_data) do
defp verify_older_version(creation_code, contract_code, check_func) do
creation_code
|> String.split(contract_code)
|> List.last()
|> Kernel.==(arguments_data)
|> check_func.()
end
defp extract_constructor_arguments(code, passed_constructor_arguments) do
defp extract_constructor_arguments(code, check_func) do
case code do
# Solidity ~ 4.23 # https://solidity.readthedocs.io/en/v0.4.23/metadata.html
"a165627a7a72305820" <> <<_::binary-size(64)>> <> "0029" <> constructor_arguments ->
if passed_constructor_arguments == constructor_arguments do
true
check_func_result = check_func.(constructor_arguments)
if check_func_result do
check_func_result
else
extract_constructor_arguments(constructor_arguments, passed_constructor_arguments)
extract_constructor_arguments(constructor_arguments, check_func)
end
# Solidity >= 0.5.10 https://solidity.readthedocs.io/en/v0.5.10/metadata.html
"a265627a7a72305820" <>
<<_::binary-size(64)>> <> "64736f6c6343" <> <<_::binary-size(6)>> <> "0032" <> constructor_arguments ->
if passed_constructor_arguments == constructor_arguments do
true
check_func_result = check_func.(constructor_arguments)
if check_func_result do
check_func_result
else
extract_constructor_arguments(constructor_arguments, passed_constructor_arguments)
extract_constructor_arguments(constructor_arguments, check_func)
end
# Solidity >= 0.5.11 https://github.com/ethereum/solidity/blob/develop/Changelog.md#0511-2019-08-12
# Metadata: Update the swarm hash to the current specification, changes bzzr0 to bzzr1 and urls to use bzz-raw://
"a265627a7a72315820" <>
<<_::binary-size(64)>> <> "64736f6c6343" <> <<_::binary-size(6)>> <> "0032" <> constructor_arguments ->
if passed_constructor_arguments == constructor_arguments do
true
check_func_result = check_func.(constructor_arguments)
if check_func_result do
check_func_result
else
extract_constructor_arguments(constructor_arguments, passed_constructor_arguments)
extract_constructor_arguments(constructor_arguments, check_func)
end
<<>> ->
passed_constructor_arguments == ""
check_func.("")
<<_::binary-size(2)>> <> rest ->
extract_constructor_arguments(rest, passed_constructor_arguments)
extract_constructor_arguments(rest, check_func)
end
end
def find_constructor_arguments(address_hash, abi) do
creation_code =
address_hash
|> Chain.contract_creation_input_data()
|> String.replace("0x", "")
constructor_abi = Enum.find(abi, fn el -> el["type"] == "constructor" && el["inputs"] != [] end)
input_types = Enum.map(constructor_abi["inputs"], &FunctionSelector.parse_specification_type/1)
check_func = fn assumed_arguments ->
try do
_ =
assumed_arguments
|> Base.decode16!(case: :mixed)
|> TypeDecoder.decode_raw(input_types)
assumed_arguments
rescue
_ -> false
end
end
extract_constructor_arguments(creation_code, check_func)
end
end

@ -101,7 +101,11 @@ defmodule Explorer.Token.InstanceMetadataRetriever do
{:ok, %Response{body: body, status_code: 200}} ->
{:ok, json} = decode_json(body)
{:ok, %{metadata: json}}
if is_map(json) do
{:ok, %{metadata: json}}
else
{:error, :wrong_metadata_type}
end
{:ok, %Response{body: body}} ->
{:error, body}

File diff suppressed because one or more lines are too long

@ -6,63 +6,65 @@ defmodule Explorer.SmartContract.Verifier.ConstructorArgumentsTest do
alias Explorer.Chain.Data
alias Explorer.SmartContract.Verifier.ConstructorArguments
test "veriies constructor constructor arguments with whisper data" do
constructor_arguments = Base.encode16(:crypto.strong_rand_bytes(64), case: :lower)
address = insert(:address)
describe "verify/3" do
test "veriies constructor constructor arguments with whisper data" do
constructor_arguments = Base.encode16(:crypto.strong_rand_bytes(64), case: :lower)
address = insert(:address)
input =
"a165627a7a72305820" <>
Base.encode16(:crypto.strong_rand_bytes(32), case: :lower) <> "0029" <> constructor_arguments
input =
"a165627a7a72305820" <>
Base.encode16(:crypto.strong_rand_bytes(32), case: :lower) <> "0029" <> constructor_arguments
input_data = %Data{
bytes: Base.decode16!(input, case: :lower)
}
input_data = %Data{
bytes: Base.decode16!(input, case: :lower)
}
:transaction
|> insert(created_contract_address_hash: address.hash, input: input_data)
|> with_block()
:transaction
|> insert(created_contract_address_hash: address.hash, input: input_data)
|> with_block()
assert ConstructorArguments.verify(address.hash, "", constructor_arguments)
end
assert ConstructorArguments.verify(address.hash, "", constructor_arguments)
end
test "verifies with multiple nested constructor arguments" do
address = insert(:address)
test "verifies with multiple nested constructor arguments" do
address = insert(:address)
constructor_arguments =
"000000000000000000000000314159265dd8dbb310642f98f50c066173c1259b93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae00000000000000000000000000000000000000000000000000000000590b09b0"
constructor_arguments =
"000000000000000000000000314159265dd8dbb310642f98f50c066173c1259b93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae00000000000000000000000000000000000000000000000000000000590b09b0"
input =
"a165627a7a72305820fbfa6f8a2024760ef0e0eb29a332c9a820526e92f8b4fbcce6f00c7643234b1400297b6c4b278d165a6b33958f8ea5dfb00c8c9d4d0acf1985bef5d10786898bc3e7a165627a7a723058203c2db82e7c80cd1e371fe349b03d49b812c324ba4a3fcd063b7bc2662353c5de0029000000000000000000000000314159265dd8dbb310642f98f50c066173c1259b93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae00000000000000000000000000000000000000000000000000000000590b09b0"
input =
"a165627a7a72305820fbfa6f8a2024760ef0e0eb29a332c9a820526e92f8b4fbcce6f00c7643234b1400297b6c4b278d165a6b33958f8ea5dfb00c8c9d4d0acf1985bef5d10786898bc3e7a165627a7a723058203c2db82e7c80cd1e371fe349b03d49b812c324ba4a3fcd063b7bc2662353c5de0029000000000000000000000000314159265dd8dbb310642f98f50c066173c1259b93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae00000000000000000000000000000000000000000000000000000000590b09b0"
input_data = %Data{
bytes: Base.decode16!(input, case: :lower)
}
input_data = %Data{
bytes: Base.decode16!(input, case: :lower)
}
:transaction
|> insert(created_contract_address_hash: address.hash, input: input_data)
|> with_block()
:transaction
|> insert(created_contract_address_hash: address.hash, input: input_data)
|> with_block()
assert ConstructorArguments.verify(address.hash, "", constructor_arguments)
end
assert ConstructorArguments.verify(address.hash, "", constructor_arguments)
end
test "verifies older version of Solidity where constructor_arguments were directly appended to source code" do
address = insert(:address)
test "verifies older version of Solidity where constructor_arguments were directly appended to source code" do
address = insert(:address)
constructor_arguments =
"000000000000000000000000314159265dd8dbb310642f98f50c066173c1259b93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae00000000000000000000000000000000000000000000000000000000590b09b0"
constructor_arguments =
"000000000000000000000000314159265dd8dbb310642f98f50c066173c1259b93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae00000000000000000000000000000000000000000000000000000000590b09b0"
source_code = "0001"
source_code = "0001"
input = source_code <> constructor_arguments
input = source_code <> constructor_arguments
input_data = %Data{
bytes: Base.decode16!(input, case: :lower)
}
input_data = %Data{
bytes: Base.decode16!(input, case: :lower)
}
:transaction
|> insert(created_contract_address_hash: address.hash, input: input_data)
|> with_block()
:transaction
|> insert(created_contract_address_hash: address.hash, input: input_data)
|> with_block()
assert ConstructorArguments.verify(address.hash, source_code, constructor_arguments)
assert ConstructorArguments.verify(address.hash, source_code, constructor_arguments)
end
end
end

Loading…
Cancel
Save