Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions newsfragments/3754.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix decoding of `argument_types` for `tuple` types in `base_contract.py`.
37 changes: 31 additions & 6 deletions tests/core/contracts/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,10 @@
)
from web3._utils.contract_sources.contract_data.tuple_contracts import (
NESTED_TUPLE_CONTRACT_DATA,
TUPLE_CONTRACT_ABI,
TUPLE_CONTRACT_BYTECODE,
TUPLE_CONTRACT_DATA,
TUPLE_CONTRACT_RUNTIME,
)
from web3.exceptions import (
Web3ValueError,
Expand Down Expand Up @@ -117,6 +120,34 @@ def math_contract(w3, math_contract_factory, address_conversion_func):
return deploy(w3, math_contract_factory, address_conversion_func)


# --- tuple contract --- #


@pytest.fixture(scope="session")
def tuple_contract_bytecode():
return TUPLE_CONTRACT_BYTECODE


@pytest.fixture(scope="session")
def tuple_contract_runtime():
return TUPLE_CONTRACT_RUNTIME


@pytest.fixture(scope="session")
def tuple_contract_abi():
return TUPLE_CONTRACT_ABI


@pytest.fixture
def tuple_contract_factory(w3):
return w3.eth.contract(**TUPLE_CONTRACT_DATA)


@pytest.fixture
def tuple_contract(w3, tuple_contract_factory, address_conversion_func):
return deploy(w3, tuple_contract_factory, address_conversion_func)


# --- constructor contracts --- #


Expand Down Expand Up @@ -471,12 +502,6 @@ def revert_contract(w3, address_conversion_func):
return deploy(w3, revert_contract_factory, address_conversion_func)


@pytest.fixture
def tuple_contract(w3, address_conversion_func):
tuple_contract_factory = w3.eth.contract(**TUPLE_CONTRACT_DATA)
return deploy(w3, tuple_contract_factory, address_conversion_func)


@pytest.fixture
def nested_tuple_contract(w3, address_conversion_func):
nested_tuple_contract_factory = w3.eth.contract(**NESTED_TUPLE_CONTRACT_DATA)
Expand Down
88 changes: 86 additions & 2 deletions tests/core/contracts/test_contract_class_construction.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ def test_error_to_call_non_existent_fallback(
math_contract.fallback.estimate_gas()


def test_contract_events_init_with_class_vars(
def test_math_contract_events_init_with_class_vars(
w3, math_contract_abi, math_contract_bytecode, math_contract_runtime
):
math_contract = w3.eth.contract(
Expand Down Expand Up @@ -125,7 +125,45 @@ def test_contract_events_init_with_class_vars(
)


def test_contract_functions_init_with_class_vars(
def test_tuple_contract_events_init_with_class_vars(
w3, tuple_contract_abi, tuple_contract_bytecode, tuple_contract_runtime
):
tuple_contract = w3.eth.contract(
abi=tuple_contract_abi,
bytecode=tuple_contract_bytecode,
bytecode_runtime=tuple_contract_runtime,
)

for event_abi in filter_abi_by_type("event", tuple_contract_abi):
# Check properties of tuple_contract.events.EventName
event_by_name = tuple_contract.events[event_abi["name"]]
if event_by_name.abi["inputs"] == event_abi["inputs"]:
assert event_by_name.name == get_name_from_abi_element_identifier(
event_abi["name"]
)
assert event_by_name.abi == event_abi
assert event_by_name.abi_element_identifier == abi_to_signature(event_abi)
assert event_by_name.signature == abi_to_signature(event_abi)
assert event_by_name.argument_names == tuple(get_abi_input_names(event_abi))
assert event_by_name.argument_types == tuple(get_abi_input_types(event_abi))

# Check properties of tuple_contract.events._EventName(arg_names)
event_by_signature = tuple_contract.events[f"_{abi_to_signature(event_abi)}"]
assert event_by_signature.name == get_name_from_abi_element_identifier(
abi_to_signature(event_abi)
)
assert event_by_signature.abi == event_abi
assert event_by_signature.abi_element_identifier == abi_to_signature(event_abi)
assert event_by_signature.signature == abi_to_signature(event_abi)
assert event_by_signature.argument_names == tuple(
get_abi_input_names(event_abi)
)
assert event_by_signature.argument_types == tuple(
get_abi_input_types(event_abi)
)


def test_math_contract_functions_init_with_class_vars(
w3, math_contract_abi, math_contract_bytecode, math_contract_runtime
):
math_contract = w3.eth.contract(
Expand Down Expand Up @@ -171,6 +209,52 @@ def test_contract_functions_init_with_class_vars(
)


def test_tuple_contract_functions_init_with_class_vars(
w3, tuple_contract_abi, tuple_contract_bytecode, tuple_contract_runtime
):
tuple_contract = w3.eth.contract(
abi=tuple_contract_abi,
bytecode=tuple_contract_bytecode,
bytecode_runtime=tuple_contract_runtime,
)

for function_abi in filter_abi_by_type("function", tuple_contract_abi):
# Check properties of tuple_contract.functions.FunctionName
function_by_name = tuple_contract.functions[function_abi["name"]]
if function_by_name.abi["inputs"] == function_abi["inputs"]:
assert function_by_name.name == get_name_from_abi_element_identifier(
function_abi["name"]
)
assert function_by_name.abi == function_abi
assert function_by_name.abi_element_identifier == abi_to_signature(
function_abi
)
assert function_by_name.signature == abi_to_signature(function_abi)
assert function_by_name.argument_names == tuple(
get_abi_input_names(function_abi)
)
assert function_by_name.argument_types == tuple(
get_abi_input_types(function_abi)
)

# Check properties of tuple_contract.functions._functionName(arg_names)
function_by_signature = tuple_contract.functions[abi_to_signature(function_abi)]
assert function_by_signature.name == get_name_from_abi_element_identifier(
abi_to_signature(function_abi)
)
assert function_by_signature.abi == function_abi
assert function_by_signature.abi_element_identifier == abi_to_signature(
function_abi
)
assert function_by_signature.signature == abi_to_signature(function_abi)
assert function_by_signature.argument_names == tuple(
get_abi_input_names(function_abi)
)
assert function_by_signature.argument_types == tuple(
get_abi_input_types(function_abi)
)


@pytest.mark.parametrize(
"abi,namespace,expected_exception",
(
Expand Down
4 changes: 4 additions & 0 deletions web3/_utils/contract_sources/TupleContracts.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ contract TupleContract {
struct T { int x; bool[2] y; address[] z; }
struct S { uint a; uint[] b; T[] c; }

event MethodCalled(S s);

function method(S memory s) public pure returns (S memory) {
return s;
}
Expand All @@ -14,6 +16,8 @@ contract NestedTupleContract {
struct T { U[] u; }
struct S { T[] t; }

event MethodCalled(S s);

function method(S memory s) public pure returns (S memory) {
return s;
}
Expand Down
Loading