|
|
|
@ -5,84 +5,57 @@ defmodule Explorer.SmartContract.VerifierTest do |
|
|
|
|
doctest Explorer.SmartContract.Verifier |
|
|
|
|
|
|
|
|
|
alias Explorer.SmartContract.Verifier |
|
|
|
|
alias Explorer.Factory |
|
|
|
|
|
|
|
|
|
describe "evaluate_authenticity/2" do |
|
|
|
|
test "verifies the generated bytecode against bytecode retrieved from the blockchain" do |
|
|
|
|
address_hash = "0x0f95fa9bc0383e699325f2658d04e8d96d87b90c" |
|
|
|
|
|
|
|
|
|
smart_contract_bytecode = |
|
|
|
|
"0x608060405234801561001057600080fd5b5060df8061001f6000396000f3006080604052600436106049576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806360fe47b114604e5780636d4ce63c146078575b600080fd5b348015605957600080fd5b5060766004803603810190808035906020019092919050505060a0565b005b348015608357600080fd5b50608a60aa565b6040518082815260200191505060405180910390f35b8060008190555050565b600080549050905600a165627a7a7230582040d82a7379b1ee1632ad4d8a239954fd940277b25628ead95259a85c5eddb2120029" |
|
|
|
|
|
|
|
|
|
created_contract_address = insert(:address, hash: address_hash, contract_code: smart_contract_bytecode) |
|
|
|
|
|
|
|
|
|
transaction = |
|
|
|
|
:transaction |
|
|
|
|
|> insert() |
|
|
|
|
|> with_block() |
|
|
|
|
setup do |
|
|
|
|
{:ok, contract_code_info: Factory.contract_code_info()} |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
insert( |
|
|
|
|
:internal_transaction_create, |
|
|
|
|
transaction: transaction, |
|
|
|
|
index: 0, |
|
|
|
|
created_contract_address: created_contract_address, |
|
|
|
|
created_contract_code: smart_contract_bytecode |
|
|
|
|
) |
|
|
|
|
test "verifies the generated bytecode against bytecode retrieved from the blockchain", %{ |
|
|
|
|
contract_code_info: contract_code_info |
|
|
|
|
} do |
|
|
|
|
contract_address = insert(:contract_address, contract_code: contract_code_info.bytecode) |
|
|
|
|
|
|
|
|
|
params = %{ |
|
|
|
|
"contract_source_code" => |
|
|
|
|
"pragma solidity ^0.4.24; contract SimpleStorage { uint storedData; function set(uint x) public { storedData = x; } function get() public constant returns (uint) { return storedData; } }", |
|
|
|
|
"compiler" => "0.4.24", |
|
|
|
|
"name" => "SimpleStorage", |
|
|
|
|
"optimization" => false |
|
|
|
|
"contract_source_code" => contract_code_info.source_code, |
|
|
|
|
"compiler_version" => contract_code_info.version, |
|
|
|
|
"name" => contract_code_info.name, |
|
|
|
|
"optimization" => contract_code_info.optimized |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
assert {:ok, %{abi: abi}} = Verifier.evaluate_authenticity(address_hash, params) |
|
|
|
|
assert {:ok, %{abi: abi}} = Verifier.evaluate_authenticity(contract_address.hash, params) |
|
|
|
|
assert abi != nil |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
test "returns error when bytecoed doesn't match" do |
|
|
|
|
address_hash = "0x0f95fa9bc0383e699325f2658d04e8d96d87b90c" |
|
|
|
|
test "returns error when bytecode doesn't match", %{contract_code_info: contract_code_info} do |
|
|
|
|
contract_address = insert(:contract_address, contract_code: contract_code_info.bytecode) |
|
|
|
|
|
|
|
|
|
wrong_smart_contract_bytecode = |
|
|
|
|
"0x6080604052600436106049576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806360fe47b114604e5780636d4ce63c146078575b600080fd5b348015605957600080fd5b5060766004803603810190808035906020019092919050505060a0565b005b348015608357600080fd5b50608a60aa565b6040518082815260200191505060405180910390f35b8060008190555050565b600080549050905600a165627a7a723058207722b6ddfe522b31e50b878ced2f22d051e8e2cd19be7b4fba9686602b90ba2b0029" |
|
|
|
|
|
|
|
|
|
created_contract_address = insert(:address, hash: address_hash, contract_code: wrong_smart_contract_bytecode) |
|
|
|
|
|
|
|
|
|
transaction = |
|
|
|
|
:transaction |
|
|
|
|
|> insert() |
|
|
|
|
|> with_block() |
|
|
|
|
|
|
|
|
|
insert( |
|
|
|
|
:internal_transaction_create, |
|
|
|
|
transaction: transaction, |
|
|
|
|
index: 0, |
|
|
|
|
created_contract_address: created_contract_address, |
|
|
|
|
created_contract_code: wrong_smart_contract_bytecode |
|
|
|
|
) |
|
|
|
|
different_code = "pragma solidity ^0.4.24; contract SimpleStorage {}" |
|
|
|
|
|
|
|
|
|
params = %{ |
|
|
|
|
"contract_source_code" => |
|
|
|
|
"pragma solidity ^0.4.24; contract SimpleStorage { uint storedData; function set(uint x) public { storedData = x; } function get() public constant returns (uint) { return storedData; } }", |
|
|
|
|
"compiler" => "0.4.24", |
|
|
|
|
"name" => "SimpleStorage", |
|
|
|
|
"optimization" => false |
|
|
|
|
"contract_source_code" => different_code, |
|
|
|
|
"compiler_version" => contract_code_info.version, |
|
|
|
|
"name" => contract_code_info.name, |
|
|
|
|
"optimization" => contract_code_info.optimized |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
assert {:error, :generated_bytecode} = Verifier.evaluate_authenticity(address_hash, params) |
|
|
|
|
response = Verifier.evaluate_authenticity(contract_address.hash, params) |
|
|
|
|
|
|
|
|
|
assert {:error, :generated_bytecode} = response |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
test "returns error when there is a compilation problem" do |
|
|
|
|
address_hash = "0x0f95fa9bc0383e699325f2658d04e8d96d87b90c" |
|
|
|
|
test "returns error when there is a compilation problem", %{contract_code_info: contract_code_info} do |
|
|
|
|
contract_address = insert(:contract_address, contract_code: contract_code_info.bytecode) |
|
|
|
|
|
|
|
|
|
params = %{ |
|
|
|
|
"contract_source_code" => "pragma solidity ^0.4.24; contract SimpleStorage { ", |
|
|
|
|
"compiler" => "0.4.24", |
|
|
|
|
"name" => "SimpleStorage", |
|
|
|
|
"optimization" => false |
|
|
|
|
"compiler_version" => contract_code_info.version, |
|
|
|
|
"name" => contract_code_info.name, |
|
|
|
|
"optimization" => contract_code_info.optimized |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
assert {:error, :compilation} = Verifier.evaluate_authenticity(address_hash, params) |
|
|
|
|
assert {:error, :compilation} = Verifier.evaluate_authenticity(contract_address.hash, params) |
|
|
|
|
end |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|