diff --git a/docs/guide/deploying_contracts.rst b/docs/guide/deploying_contracts.rst index bd63067d1..a3780c6d7 100644 --- a/docs/guide/deploying_contracts.rst +++ b/docs/guide/deploying_contracts.rst @@ -14,17 +14,6 @@ Here's an example how to use it. :dedent: 4 -Simple declare and deploy -------------------------- - -The simplest way of declaring and deploying contracts on the Starknet is to use the :ref:`Contract` class. -Under the hood, this flow first sends ``Declare`` transaction and then sends ``Invoke`` -through Universal Deployment Contract (UDC) to deploy a contract. - -.. codesnippet:: ../../starknet_py/tests/e2e/docs/guide/test_simple_declare_and_deploy.py - :language: python - :dedent: 4 - Simple deploy ------------- diff --git a/starknet_py/abi/v1/schemas_test.py b/starknet_py/abi/v1/schemas_test.py index e098e9730..7a0765d13 100644 --- a/starknet_py/abi/v1/schemas_test.py +++ b/starknet_py/abi/v1/schemas_test.py @@ -11,11 +11,11 @@ "contract_name", [ "Account", - "ERC20", + "Hello", "HelloStarknet", "MinimalContract", "TestContract", - "TokenBridge", + "TestEnum", ], ) def test_deserialize_abi(contract_name): diff --git a/starknet_py/serialization/serialization_test.py b/starknet_py/serialization/serialization_test.py index d9f0a56ce..b60a6363d 100644 --- a/starknet_py/serialization/serialization_test.py +++ b/starknet_py/serialization/serialization_test.py @@ -14,6 +14,7 @@ serializer_for_function, ) from starknet_py.serialization.tuple_dataclass import TupleDataclass +from starknet_py.tests.e2e.fixtures.abi_v1_structures import event_abi_v1 from starknet_py.tests.e2e.fixtures.constants import CONTRACTS_COMPILED_V0_DIR from starknet_py.tests.e2e.fixtures.misc import ( ContractVersion, @@ -110,10 +111,7 @@ class Education(NamedTuple): ) parsed_abi = AbiParserV0(abi).parse() -abi_v1 = json.loads( - load_contract(contract_name="ERC20", version=ContractVersion.V1)["sierra"] -)["abi"] -parsed_abi_v1 = AbiParserV1(abi_v1).parse() +parsed_abi_v1 = AbiParserV1(event_abi_v1).parse() abi_v2 = json.loads( load_contract(contract_name="NewSyntaxTestContract", version=ContractVersion.V2)[ diff --git a/starknet_py/tests/e2e/account/account_test.py b/starknet_py/tests/e2e/account/account_test.py index 03bde9513..d1cd876f9 100644 --- a/starknet_py/tests/e2e/account/account_test.py +++ b/starknet_py/tests/e2e/account/account_test.py @@ -57,8 +57,8 @@ async def test_get_balance_throws_when_token_not_specified(account): @pytest.mark.skipif( - "--contract_dir=v2" not in sys.argv, - reason="Some cairo 1 contracts compiled with v1 compiler fail with new starknet-devnet-rs", + "--contract_dir=v1" in sys.argv, + reason="Contract exists only in v2 directory", ) @pytest.mark.asyncio async def test_balance_when_token_specified(account, erc20_contract): @@ -68,8 +68,8 @@ async def test_balance_when_token_specified(account, erc20_contract): @pytest.mark.skipif( - "--contract_dir=v2" not in sys.argv, - reason="Some cairo 1 contracts compiled with v1 compiler fail with new starknet-devnet-rs", + "--contract_dir=v1" in sys.argv, + reason="Contract exists only in v2 directory", ) @pytest.mark.asyncio async def test_estimated_fee_greater_than_zero(account, erc20_contract): @@ -88,9 +88,14 @@ async def test_estimated_fee_greater_than_zero(account, erc20_contract): @pytest.mark.asyncio -async def test_estimate_fee_for_declare_transaction(account, map_compiled_contract): - declare_tx = await account.sign_declare_v1( - compiled_contract=map_compiled_contract, max_fee=MAX_FEE +async def test_estimate_fee_for_declare_transaction( + account, map_compiled_contract_and_class_hash +): + (compiled_contract, class_hash) = map_compiled_contract_and_class_hash + declare_tx = await account.sign_declare_v3( + compiled_contract=compiled_contract, + compiled_class_hash=class_hash, + l1_resource_bounds=MAX_RESOURCE_BOUNDS_L1, ) estimated_fee = await account.client.estimate_fee(tx=declare_tx) @@ -106,15 +111,18 @@ async def test_estimate_fee_for_declare_transaction(account, map_compiled_contra @pytest.mark.asyncio async def test_account_estimate_fee_for_declare_transaction( - account, map_compiled_contract + account, map_compiled_contract_and_class_hash ): - declare_tx = await account.sign_declare_v1( - compiled_contract=map_compiled_contract, max_fee=MAX_FEE + (compiled_contract, class_hash) = map_compiled_contract_and_class_hash + declare_tx = await account.sign_declare_v3( + compiled_contract=compiled_contract, + compiled_class_hash=class_hash, + l1_resource_bounds=MAX_RESOURCE_BOUNDS_L1, ) estimated_fee = await account.estimate_fee(tx=declare_tx) - assert estimated_fee.unit == PriceUnit.WEI + assert estimated_fee.unit == PriceUnit.FRI assert isinstance(estimated_fee.overall_fee, int) assert estimated_fee.overall_fee > 0 assert ( diff --git a/starknet_py/tests/e2e/block_test.py b/starknet_py/tests/e2e/block_test.py index a7f34c926..529071b57 100644 --- a/starknet_py/tests/e2e/block_test.py +++ b/starknet_py/tests/e2e/block_test.py @@ -37,15 +37,12 @@ async def test_block_with_tx_hashes_pending(account): # TODO (#1419): Fix contract redeclaration @pytest.mark.skip(reason="Redeclaration occurred") @pytest.mark.asyncio -async def test_block_with_tx_hashes_latest( - account, - map_contract_declare_hash, -): +async def test_block_with_tx_hashes_latest(account): blk = await account.client.get_block_with_tx_hashes(block_number="latest") assert isinstance(blk, StarknetBlockWithTxHashes) assert isinstance(blk.transactions, list) - assert map_contract_declare_hash in blk.transactions + assert blk.transactions is not None assert blk.block_hash is not None assert blk.parent_hash is not None assert blk.block_number is not None @@ -68,17 +65,15 @@ async def test_get_block_with_txs_pending(account): # TODO (#1419): Fix contract redeclaration -@pytest.mark.skip(reason="Redeclaration occurred") @pytest.mark.asyncio -async def test_get_block_with_txs_latest( - account, - map_contract_declare_hash, -): +async def test_get_block_with_txs_latest(account, map_class_hash): + # pylint: disable=unused-argument + blk = await account.client.get_block_with_txs(block_number="latest") assert isinstance(blk, StarknetBlock) assert isinstance(blk.transactions, list) - assert blk.transactions[0].hash == map_contract_declare_hash + assert blk.transactions[0].hash is not None assert blk.block_hash is not None assert blk.parent_hash is not None assert blk.block_number is not None diff --git a/starknet_py/tests/e2e/client/client_test.py b/starknet_py/tests/e2e/client/client_test.py index fc5be59a0..4b80e4615 100644 --- a/starknet_py/tests/e2e/client/client_test.py +++ b/starknet_py/tests/e2e/client/client_test.py @@ -1,5 +1,4 @@ # pylint: disable=too-many-arguments -import dataclasses from typing import Tuple from unittest.mock import AsyncMock, Mock, patch @@ -37,8 +36,7 @@ from starknet_py.net.http_client import RpcHttpClient from starknet_py.net.models.transaction import DeclareV2 from starknet_py.net.udc_deployer.deployer import Deployer -from starknet_py.tests.e2e.fixtures.constants import CONTRACTS_COMPILED_V0_DIR, MAX_FEE -from starknet_py.tests.e2e.fixtures.misc import read_contract +from starknet_py.tests.e2e.fixtures.constants import MAX_FEE from starknet_py.transaction_errors import ( TransactionNotReceivedError, TransactionRejectedError, @@ -249,16 +247,7 @@ async def test_estimate_fee_for_multiple_transactions( ) invoke_tx = await account.sign_for_fee_estimate(invoke_tx) - declare_tx = await account.sign_declare_v1( - compiled_contract=read_contract( - "map_compiled.json", directory=CONTRACTS_COMPILED_V0_DIR - ), - max_fee=MAX_FEE, - ) - declare_tx = dataclasses.replace(declare_tx, nonce=invoke_tx.nonce + 1) - declare_tx = await account.sign_for_fee_estimate(declare_tx) - - transactions = [invoke_tx, declare_tx, deploy_account_transaction] + transactions = [invoke_tx, deploy_account_transaction] estimated_fees = await client.estimate_fee(tx=transactions, block_number="latest") diff --git a/starknet_py/tests/e2e/client/fixtures/transactions.py b/starknet_py/tests/e2e/client/fixtures/transactions.py index 27ca47a1c..6ac67e52a 100644 --- a/starknet_py/tests/e2e/client/fixtures/transactions.py +++ b/starknet_py/tests/e2e/client/fixtures/transactions.py @@ -1,5 +1,5 @@ # pylint: disable=redefined-outer-name -from typing import Tuple, cast +from typing import Tuple import pytest import pytest_asyncio @@ -12,8 +12,7 @@ from starknet_py.tests.e2e.client.fixtures.prepare_net_for_gateway_test import ( PreparedNetworkData, ) -from starknet_py.tests.e2e.fixtures.constants import CONTRACTS_COMPILED_V0_DIR, MAX_FEE -from starknet_py.tests.e2e.fixtures.misc import read_contract +from starknet_py.tests.e2e.fixtures.constants import MAX_FEE from starknet_py.tests.e2e.utils import ( get_deploy_account_details, get_deploy_account_transaction, @@ -94,31 +93,3 @@ async def block_with_declare_v2_number( cairo1_hello_starknet_tx_hash ) return declare_v2_receipt.block_number - - -@pytest_asyncio.fixture(scope="function") -async def replaced_class(account: Account, map_class_hash: int) -> Tuple[int, int, int]: - """ - Returns block_number, contract_address and class_hash of transaction replacing implementation. - """ - compiled_contract = read_contract( - "replace_class_compiled.json", directory=CONTRACTS_COMPILED_V0_DIR - ) - - declare_result = await ( - await Contract.declare_v1(account, compiled_contract, max_fee=MAX_FEE) - ).wait_for_acceptance() - - deploy_result = await ( - await declare_result.deploy_v1(max_fee=MAX_FEE) - ).wait_for_acceptance() - - contract = deploy_result.deployed_contract - - resp = await ( - await contract.functions["replace_implementation"].invoke_v1( - new_class=map_class_hash, max_fee=MAX_FEE - ) - ).wait_for_acceptance() - - return cast(int, resp.block_number), contract.address, map_class_hash diff --git a/starknet_py/tests/e2e/client/full_node_test.py b/starknet_py/tests/e2e/client/full_node_test.py index 7e794d37e..7b039079b 100644 --- a/starknet_py/tests/e2e/client/full_node_test.py +++ b/starknet_py/tests/e2e/client/full_node_test.py @@ -1,4 +1,5 @@ import dataclasses +import sys from unittest.mock import AsyncMock, patch import pytest @@ -26,12 +27,7 @@ ) from starknet_py.net.full_node_client import _to_rpc_felt from starknet_py.net.models import StarknetChainId -from starknet_py.tests.e2e.fixtures.constants import CONTRACTS_COMPILED_V0_DIR -from starknet_py.tests.e2e.fixtures.misc import ( - ContractVersion, - load_contract, - read_contract, -) +from starknet_py.tests.e2e.fixtures.misc import ContractVersion, load_contract from starknet_py.tests.e2e.utils import create_empty_block @@ -40,9 +36,9 @@ def _parse_event_name(event: str) -> str: FUNCTION_ONE_NAME = "put" -EVENT_ONE_PARSED_NAME = _parse_event_name("put_called") +EVENT_ONE_PARSED_NAME = _parse_event_name("PutCalled") FUNCTION_TWO_NAME = "another_put" -EVENT_TWO_PARSED_NAME = _parse_event_name("another_put_called") +EVENT_TWO_PARSED_NAME = _parse_event_name("AnotherPutCalled") # TODO (#1419): Fix contract redeclaration @@ -149,6 +145,10 @@ async def test_get_storage_at_incorrect_address_full_node_client(client): ) +@pytest.mark.skipif( + "--contract_dir=v1" in sys.argv, + reason="Contract exists only in v2 directory", +) @pytest.mark.run_on_devnet @pytest.mark.asyncio async def test_get_events_without_following_continuation_token( @@ -156,7 +156,7 @@ async def test_get_events_without_following_continuation_token( simple_storage_with_event_contract: Contract, ): for i in range(4): - await simple_storage_with_event_contract.functions[FUNCTION_ONE_NAME].invoke_v1( + await simple_storage_with_event_contract.functions[FUNCTION_ONE_NAME].invoke_v3( i, i, auto_estimate=True ) @@ -174,6 +174,10 @@ async def test_get_events_without_following_continuation_token( assert events_response.continuation_token is not None +@pytest.mark.skipif( + "--contract_dir=v1" in sys.argv, + reason="Contract exists only in v2 directory", +) @pytest.mark.run_on_devnet @pytest.mark.asyncio async def test_get_events_follow_continuation_token( @@ -199,6 +203,10 @@ async def test_get_events_follow_continuation_token( assert events_response.continuation_token is None +@pytest.mark.skipif( + "--contract_dir=v1" in sys.argv, + reason="Contract exists only in v2 directory", +) @pytest.mark.run_on_devnet @pytest.mark.asyncio async def test_get_events_nonexistent_event_name( @@ -222,6 +230,10 @@ async def test_get_events_nonexistent_event_name( assert events_response.continuation_token is None +@pytest.mark.skipif( + "--contract_dir=v1" in sys.argv, + reason="Contract exists only in v2 directory", +) @pytest.mark.run_on_devnet @pytest.mark.asyncio async def test_get_events_with_two_events( @@ -271,6 +283,10 @@ async def test_get_events_with_two_events( assert event_one_two_events_response.continuation_token is None +@pytest.mark.skipif( + "--contract_dir=v1" in sys.argv, + reason="Contract exists only in v2 directory", +) @pytest.mark.run_on_devnet @pytest.mark.asyncio async def test_get_events_start_from_continuation_token( @@ -298,6 +314,10 @@ async def test_get_events_start_from_continuation_token( assert events_response.continuation_token == expected_continuation_token +@pytest.mark.skipif( + "--contract_dir=v1" in sys.argv, + reason="Contract exists only in v2 directory", +) @pytest.mark.run_on_devnet @pytest.mark.asyncio async def test_get_events_no_params( @@ -317,6 +337,10 @@ async def test_get_events_no_params( assert len(events_response.events) == default_chunk_size +@pytest.mark.skipif( + "--contract_dir=v1" in sys.argv, + reason="Contract exists only in v2 directory", +) @pytest.mark.run_on_devnet @pytest.mark.asyncio async def test_get_events_nonexistent_starting_block( @@ -475,23 +499,6 @@ async def test_simulate_transactions_invoke(account, deployed_balance_contract): # TODO (#1419): Fix contract redeclaration @pytest.mark.skip(reason="Redeclaration occurred") -@pytest.mark.asyncio -async def test_simulate_transactions_declare(account): - compiled_contract = read_contract( - "map_compiled.json", directory=CONTRACTS_COMPILED_V0_DIR - ) - declare_tx = await account.sign_declare_v1(compiled_contract, max_fee=int(1e16)) - - simulated_txs = await account.client.simulate_transactions( - transactions=[declare_tx], block_number="latest" - ) - - assert isinstance(simulated_txs[0].transaction_trace, DeclareTransactionTrace) - assert simulated_txs[0].fee_estimation.overall_fee > 0 - assert simulated_txs[0].transaction_trace.validate_invocation is not None - assert simulated_txs[0].transaction_trace.execution_resources is not None - - @pytest.mark.asyncio async def test_simulate_transactions_two_txs(account, deployed_balance_contract): assert isinstance(deployed_balance_contract, Contract) diff --git a/starknet_py/tests/e2e/contract_interaction/declare_test.py b/starknet_py/tests/e2e/contract_interaction/declare_test.py index 0acd91410..221028a46 100644 --- a/starknet_py/tests/e2e/contract_interaction/declare_test.py +++ b/starknet_py/tests/e2e/contract_interaction/declare_test.py @@ -13,7 +13,7 @@ async def test_throws_when_cairo1_without_compiled_contract_casm_and_class_hash( "For Cairo 1.0 contracts, either the 'compiled_class_hash' or the 'compiled_contract_casm' " "argument must be provided." ) - compiled_contract = load_contract("ERC20")["sierra"] + compiled_contract = load_contract("Map")["sierra"] with pytest.raises(ValueError, match=error_message): await Contract.declare_v2( diff --git a/starknet_py/tests/e2e/contract_interaction/v1_interaction_test.py b/starknet_py/tests/e2e/contract_interaction/v1_interaction_test.py index 5dee59df9..20987836e 100644 --- a/starknet_py/tests/e2e/contract_interaction/v1_interaction_test.py +++ b/starknet_py/tests/e2e/contract_interaction/v1_interaction_test.py @@ -11,8 +11,8 @@ @pytest.mark.skipif( - "--contract_dir=v2" not in sys.argv, - reason="Some cairo 1 contracts compiled with v1 compiler fail with new starknet-devnet-rs", + "--contract_dir=v1" in sys.argv, + reason="Contract exists only in v2 directory", ) @pytest.mark.asyncio async def test_general_v1_interaction(account, cairo1_erc20_class_hash: int): @@ -57,8 +57,8 @@ async def test_general_v1_interaction(account, cairo1_erc20_class_hash: int): @pytest.mark.skipif( - "--contract_dir=v2" not in sys.argv, - reason="Some Cairo 1 contracts compiled with v1 compiler fail with new starknet-devnet-rs", + "--contract_dir=v1" in sys.argv, + reason="Contract exists only in v2 directory", ) @pytest.mark.asyncio async def test_serializing_struct(account, cairo1_token_bridge_class_hash: int): @@ -149,8 +149,8 @@ async def test_serializing_enum(account, cairo1_test_enum_class_hash: int): @pytest.mark.skipif( - "--contract_dir=v2" not in sys.argv, - reason="Some cairo 1 contracts compiled with v1 compiler fail with new starknet-devnet-rs", + "--contract_dir=v1" in sys.argv, + reason="Contract exists only in v2 directory", ) @pytest.mark.asyncio async def test_from_address_on_v1_contract(account, cairo1_erc20_class_hash: int): diff --git a/starknet_py/tests/e2e/docs/guide/test_declaring_contracts.py b/starknet_py/tests/e2e/docs/guide/test_declaring_contracts.py index 18e608134..8ae36b360 100644 --- a/starknet_py/tests/e2e/docs/guide/test_declaring_contracts.py +++ b/starknet_py/tests/e2e/docs/guide/test_declaring_contracts.py @@ -1,17 +1,25 @@ import pytest +from starknet_py.net.client_models import ResourceBounds + # TODO (#1419): Fix contract redeclaration @pytest.mark.skip(reason="Redeclaration occurred") @pytest.mark.asyncio -async def test_declaring_contracts(account, map_compiled_contract): - contract_compiled = map_compiled_contract +async def test_declaring_contracts(account, map_compiled_contract_and_class_hash): + (compiled_contract, class_hash) = map_compiled_contract_and_class_hash # docs: start - # Account.sign_declare_v1 takes contract source code or compiled contract and returns DeclareV1 transaction - # Similarly, Account.sign_declare_v2 and Account.sign_declare_v3 return DeclareV2 and DeclareV3 respectively - declare_transaction = await account.sign_declare_v1( - compiled_contract=contract_compiled, max_fee=int(1e16) + # Account.sign_declare_v2 and Account.sign_declare_v3 take string containing a compiled contract (sierra) + # and a class hash (casm_class_hash) + # They return DeclareV2 and DeclareV3 respectively + + declare_transaction = await account.sign_declare_v3( + compiled_contract=compiled_contract, + compiled_class_hash=class_hash, + l1_resource_bounds=ResourceBounds( + max_amount=5000, max_price_per_unit=int(1e12) + ), ) # To declare a contract, send Declare transaction with Client.declare method diff --git a/starknet_py/tests/e2e/docs/guide/test_deploying_in_multicall.py b/starknet_py/tests/e2e/docs/guide/test_deploying_in_multicall.py index b62d03fcd..4236318f2 100644 --- a/starknet_py/tests/e2e/docs/guide/test_deploying_in_multicall.py +++ b/starknet_py/tests/e2e/docs/guide/test_deploying_in_multicall.py @@ -1,10 +1,8 @@ import pytest -from starknet_py.common import create_compiled_contract - @pytest.mark.asyncio -async def test_deploying_in_multicall(account, map_class_hash, map_compiled_contract): +async def test_deploying_in_multicall(account, map_class_hash, map_abi): # pylint: disable=import-outside-toplevel, # docs: start from starknet_py.contract import Contract @@ -18,13 +16,11 @@ async def test_deploying_in_multicall(account, map_class_hash, map_compiled_cont class_hash=map_class_hash ) # docs: end - - map_abi = create_compiled_contract(compiled_contract=map_compiled_contract).abi # docs: start # Address of the `map` contract is known here, so we can create its instance! map_contract = Contract( - address=address, abi=map_abi, provider=account, cairo_version=0 + address=address, abi=map_abi, provider=account, cairo_version=1 ) # And now we can prepare a call diff --git a/starknet_py/tests/e2e/docs/guide/test_simple_declare_and_deploy.py b/starknet_py/tests/e2e/docs/guide/test_simple_declare_and_deploy.py index 944a26acf..e69de29bb 100644 --- a/starknet_py/tests/e2e/docs/guide/test_simple_declare_and_deploy.py +++ b/starknet_py/tests/e2e/docs/guide/test_simple_declare_and_deploy.py @@ -1,37 +0,0 @@ -import pytest - - -# TODO (#1419): Fix contract redeclaration -@pytest.mark.skip(reason="Redeclaration occurred") -@pytest.mark.asyncio -async def test_simple_declare_and_deploy(account, map_compiled_contract): - # pylint: disable=import-outside-toplevel - # docs: start - from starknet_py.contract import Contract - - # docs: end - - compiled_contract = map_compiled_contract - # docs: start - - # To declare through Contract class you have to compile a contract and pass it - # to Contract.declare_v1 or Contract.declare_v3 - declare_result = await Contract.declare_v1( - account=account, compiled_contract=compiled_contract, max_fee=int(1e18) - ) - # Wait for the transaction - await declare_result.wait_for_acceptance() - - # After contract is declared it can be deployed - deploy_result = await declare_result.deploy_v1(max_fee=int(1e18)) - await deploy_result.wait_for_acceptance() - - # You can pass more arguments to the `deploy` method. Check `API` section to learn more - - # To interact with just deployed contract get its instance from the deploy_result - contract = deploy_result.deployed_contract - - # Now, any of the contract functions can be called - # docs: end - - assert contract.address != 0 diff --git a/starknet_py/tests/e2e/docs/guide/test_simple_deploy.py b/starknet_py/tests/e2e/docs/guide/test_simple_deploy.py index 8d3ba2c87..8d0d5b86e 100644 --- a/starknet_py/tests/e2e/docs/guide/test_simple_deploy.py +++ b/starknet_py/tests/e2e/docs/guide/test_simple_deploy.py @@ -1,18 +1,20 @@ import pytest -from starknet_py.common import create_compiled_contract +from starknet_py.net.client_models import ResourceBounds @pytest.mark.asyncio -async def test_simple_deploy(account, map_class_hash, map_compiled_contract): +async def test_simple_deploy( + account, cairo1_hello_starknet_class_hash, cairo1_hello_starknet_abi +): # pylint: disable=import-outside-toplevel # docs: start from starknet_py.contract import Contract # docs: end - class_hash = map_class_hash - abi = create_compiled_contract(compiled_contract=map_compiled_contract).abi + class_hash = cairo1_hello_starknet_class_hash + abi = cairo1_hello_starknet_abi # docs: start # To deploy contract just use `Contract.deploy_contract_v1` method @@ -25,12 +27,14 @@ async def test_simple_deploy(account, map_class_hash, map_compiled_contract): constructor_args = None # docs: start - deploy_result = await Contract.deploy_contract_v1( + deploy_result = await Contract.deploy_contract_v3( account=account, class_hash=class_hash, abi=abi, constructor_args=constructor_args, - max_fee=int(1e16), + l1_resource_bounds=ResourceBounds( + max_amount=int(1e5), max_price_per_unit=int(1e13) + ), ) # `Contract.deploy_contract_v1` and `Contract.deploy_contract_v3` methods have an optional parameter diff --git a/starknet_py/tests/e2e/docs/guide/test_using_existing_contracts.py b/starknet_py/tests/e2e/docs/guide/test_using_existing_contracts.py index 2d3ebf9b1..5556bdd6e 100644 --- a/starknet_py/tests/e2e/docs/guide/test_using_existing_contracts.py +++ b/starknet_py/tests/e2e/docs/guide/test_using_existing_contracts.py @@ -26,8 +26,8 @@ @pytest.mark.skipif( - "--contract_dir=v2" not in sys.argv, - reason="Some cairo 1 contracts compiled with v1 compiler fail with new starknet-devnet-rs", + "--contract_dir=v1" in sys.argv, + reason="Contract exists only in v2 directory", ) @pytest.mark.asyncio async def test_using_existing_contracts(account, erc20_contract): diff --git a/starknet_py/tests/e2e/docs/quickstart/test_synchronous_full_node_client.py b/starknet_py/tests/e2e/docs/quickstart/test_synchronous_full_node_client.py index 2dd5433ab..8f93d9caf 100644 --- a/starknet_py/tests/e2e/docs/quickstart/test_synchronous_full_node_client.py +++ b/starknet_py/tests/e2e/docs/quickstart/test_synchronous_full_node_client.py @@ -3,6 +3,7 @@ def test_synchronous_full_node_client( client, + map_class_hash, # pylint: disable=unused-argument ): # pylint: disable=unused-variable fixture_client = client diff --git a/starknet_py/tests/e2e/docs/quickstart/test_using_account.py b/starknet_py/tests/e2e/docs/quickstart/test_using_account.py index 502384377..5867c5298 100644 --- a/starknet_py/tests/e2e/docs/quickstart/test_using_account.py +++ b/starknet_py/tests/e2e/docs/quickstart/test_using_account.py @@ -2,7 +2,7 @@ import pytest -from starknet_py.tests.e2e.fixtures.constants import MAX_FEE +from starknet_py.net.client_models import ResourceBounds directory = os.path.dirname(__file__) @@ -10,19 +10,34 @@ # TODO (#1419): Fix contract redeclaration @pytest.mark.skip(reason="Redeclaration occurred") @pytest.mark.asyncio -async def test_using_account(account, map_compiled_contract): +async def test_using_account( + account, map_compiled_contract_casm, map_compiled_contract_and_class_hash +): + (compiled_contract, _) = map_compiled_contract_and_class_hash + compiled_contract_casm = map_compiled_contract_casm # pylint: disable=import-outside-toplevel, duplicate-code, too-many-locals # docs: start from starknet_py.contract import Contract # docs: end # docs: start + l1_resource_bounds = ResourceBounds( + max_amount=int(1e5), max_price_per_unit=int(1e13) + ) # Declare and deploy an example contract which implements a simple k-v store. - declare_result = await Contract.declare_v1( - account=account, compiled_contract=map_compiled_contract, max_fee=MAX_FEE + # Contract.declare_v3 takes string containing a compiled contract (sierra) and + # a class hash (casm_class_hash) or string containing a compiled contract (casm) + declare_result = await Contract.declare_v3( + account, + compiled_contract=compiled_contract, + compiled_contract_casm=compiled_contract_casm, + l1_resource_bounds=l1_resource_bounds, ) + await declare_result.wait_for_acceptance() - deploy_result = await declare_result.deploy_v1(max_fee=MAX_FEE) + deploy_result = await declare_result.deploy_v3( + l1_resource_bounds=l1_resource_bounds, + ) # Wait until deployment transaction is accepted await deploy_result.wait_for_acceptance() @@ -32,7 +47,13 @@ async def test_using_account(account, map_compiled_contract): # Adds a transaction to mutate the state of k-v store. The call goes through account proxy, because we've used # Account to create the contract object await ( - await map_contract.functions["put"].invoke_v1(k, v, max_fee=int(1e16)) + await map_contract.functions["put"].invoke_v3( + k, + v, + l1_resource_bounds=ResourceBounds( + max_amount=int(1e5), max_price_per_unit=int(1e13) + ), + ) ).wait_for_acceptance() # Retrieves the value, which is equal to 4324 in this case @@ -42,12 +63,15 @@ async def test_using_account(account, map_compiled_contract): # Creates a list of prepared function calls calls = [ - map_contract.functions["put"].prepare_invoke_v1(key=10, value=20), - map_contract.functions["put"].prepare_invoke_v1(key=30, value=40), + map_contract.functions["put"].prepare_invoke_v3(key=10, value=20), + map_contract.functions["put"].prepare_invoke_v3(key=30, value=40), ] # Executes only one transaction with prepared calls - transaction_response = await account.execute_v1(calls=calls, max_fee=int(1e16)) + transaction_response = await account.execute_v3( + calls=calls, + l1_resource_bounds=l1_resource_bounds, + ) await account.client.wait_for_tx(transaction_response.transaction_hash) # docs: end diff --git a/starknet_py/tests/e2e/docs/quickstart/test_using_contract.py b/starknet_py/tests/e2e/docs/quickstart/test_using_contract.py index ab6dc6e66..7ca51e2c0 100644 --- a/starknet_py/tests/e2e/docs/quickstart/test_using_contract.py +++ b/starknet_py/tests/e2e/docs/quickstart/test_using_contract.py @@ -34,7 +34,7 @@ async def test_using_contract(account, map_contract): address=contract_address, abi=abi, provider=account, - cairo_version=0, + cairo_version=1, ) # All exposed functions are available at contract.functions. diff --git a/starknet_py/tests/e2e/fixtures/abi_v1_structures.py b/starknet_py/tests/e2e/fixtures/abi_v1_structures.py index a33a5ae3a..6332258fe 100644 --- a/starknet_py/tests/e2e/fixtures/abi_v1_structures.py +++ b/starknet_py/tests/e2e/fixtures/abi_v1_structures.py @@ -177,3 +177,21 @@ functions={}, defined_enums={}, ) + +event_abi_v1 = [ + { + "type": "event", + "name": "Approval", + "inputs": [ + { + "name": "owner", + "type": "core::starknet::contract_address::ContractAddress", + }, + { + "name": "spender", + "type": "core::starknet::contract_address::ContractAddress", + }, + {"name": "value", "type": "core::integer::u256"}, + ], + } +] diff --git a/starknet_py/tests/e2e/fixtures/contracts.py b/starknet_py/tests/e2e/fixtures/contracts.py index 384277e1a..5ea6a7ff0 100644 --- a/starknet_py/tests/e2e/fixtures/contracts.py +++ b/starknet_py/tests/e2e/fixtures/contracts.py @@ -4,11 +4,7 @@ import pytest import pytest_asyncio -from starknet_py.common import ( - create_casm_class, - create_compiled_contract, - create_sierra_compiled_contract, -) +from starknet_py.common import create_casm_class, create_sierra_compiled_contract from starknet_py.constants import FEE_CONTRACT_ADDRESS from starknet_py.contract import Contract from starknet_py.hash.casm_class_hash import compute_casm_class_hash @@ -16,7 +12,6 @@ from starknet_py.net.udc_deployer.deployer import Deployer from starknet_py.tests.e2e.fixtures.constants import ( CONTRACTS_COMPILED_V0_DIR, - CONTRACTS_DIR, MAX_FEE, PRECOMPILED_CONTRACTS_DIR, STRK_FEE_CONTRACT_ADDRESS, @@ -28,22 +23,6 @@ ) -@pytest.fixture(scope="package") -def map_source_code() -> str: - """ - Returns source code of the map contract. - """ - return read_contract("map.cairo", directory=CONTRACTS_DIR) - - -@pytest.fixture(scope="package") -def map_compiled_contract() -> str: - """ - Returns compiled map contract. - """ - return read_contract("map_compiled.json", directory=CONTRACTS_COMPILED_V0_DIR) - - @pytest.fixture(scope="package") def sierra_minimal_compiled_contract_and_class_hash() -> Tuple[str, int]: """ @@ -70,16 +49,6 @@ def abi_types_compiled_contract_and_class_hash() -> Tuple[str, int]: ) -@pytest.fixture(scope="package") -def simple_storage_with_event_compiled_contract() -> str: - """ - Returns compiled simple storage contract that emits an event. - """ - return read_contract( - "simple_storage_with_event_compiled.json", directory=CONTRACTS_COMPILED_V0_DIR - ) - - async def deploy_contract(account: BaseAccount, class_hash: int, abi: List) -> Contract: """ Deploys a contract and returns its instance. @@ -144,48 +113,6 @@ async def deployed_balance_contract( return deploy_result.deployed_contract -@pytest_asyncio.fixture(scope="package") -async def map_contract( - account: BaseAccount, - map_compiled_contract: str, - map_class_hash: int, -) -> Contract: - """ - Deploys map contract and returns its instance. - """ - abi = create_compiled_contract(compiled_contract=map_compiled_contract).abi - return await deploy_contract(account, map_class_hash, abi) - - -@pytest_asyncio.fixture(scope="package") -async def map_contract_declare_hash( - account: BaseAccount, - map_compiled_contract: str, -): - declare_result = await Contract.declare_v1( - account=account, - compiled_contract=map_compiled_contract, - max_fee=MAX_FEE, - ) - await declare_result.wait_for_acceptance() - return declare_result.hash - - -@pytest_asyncio.fixture(scope="function") -async def simple_storage_with_event_contract( - account: BaseAccount, - simple_storage_with_event_compiled_contract: str, - simple_storage_with_event_class_hash: int, -) -> Contract: - """ - Deploys storage contract with an events and returns its instance. - """ - abi = create_compiled_contract( - compiled_contract=simple_storage_with_event_compiled_contract - ).abi - return await deploy_contract(account, simple_storage_with_event_class_hash, abi) - - @pytest.fixture(scope="package") def eth_fee_contract(account: BaseAccount, fee_contract_abi) -> Contract: """ @@ -238,14 +165,6 @@ def fee_contract_abi(): ] -@pytest.fixture(name="balance_contract") -def fixture_balance_contract() -> str: - """ - Returns compiled code of the balance.cairo contract. - """ - return read_contract("balance_compiled.json", directory=CONTRACTS_COMPILED_V0_DIR) - - async def declare_account(account: BaseAccount, compiled_account_contract: str) -> int: """ Declares a specified account. @@ -312,33 +231,3 @@ async def argent_cairo1_account_class_hash( compiled_account_contract=compiled_contract, compiled_account_contract_casm=compiled_contract_casm, ) - - -@pytest_asyncio.fixture(scope="package") -async def map_class_hash(account: BaseAccount, map_compiled_contract: str) -> int: - """ - Returns class_hash of the map.cairo. - """ - declare = await account.sign_declare_v1( - compiled_contract=map_compiled_contract, - max_fee=int(1e16), - ) - res = await account.client.declare(declare) - await account.client.wait_for_tx(res.transaction_hash) - return res.class_hash - - -@pytest_asyncio.fixture(scope="package") -async def simple_storage_with_event_class_hash( - account: BaseAccount, simple_storage_with_event_compiled_contract: str -): - """ - Returns class_hash of the simple_storage_with_event.cairo - """ - declare = await account.sign_declare_v1( - compiled_contract=simple_storage_with_event_compiled_contract, - max_fee=int(1e16), - ) - res = await account.client.declare(declare) - await account.client.wait_for_tx(res.transaction_hash) - return res.class_hash diff --git a/starknet_py/tests/e2e/fixtures/contracts_v1.py b/starknet_py/tests/e2e/fixtures/contracts_v1.py index 2b854250e..360aa1d9e 100644 --- a/starknet_py/tests/e2e/fixtures/contracts_v1.py +++ b/starknet_py/tests/e2e/fixtures/contracts_v1.py @@ -84,6 +84,16 @@ async def cairo1_hello_starknet_class_hash_tx_hash( return resp.class_hash, resp.transaction_hash +@pytest_asyncio.fixture(scope="package") +async def cairo1_hello_starknet_abi() -> List: + contract = load_contract("HelloStarknet") + compiled_contract = create_sierra_compiled_contract( + compiled_contract=contract["sierra"] + ) + assert compiled_contract.parsed_abi is not None + return compiled_contract.parsed_abi + + @pytest.fixture(scope="package") def cairo1_hello_starknet_class_hash( cairo1_hello_starknet_class_hash_tx_hash: Tuple[int, int] @@ -190,3 +200,71 @@ async def deploy_string_contract( contract_name="MyString", class_hash=string_contract_class_hash, ) + + +@pytest_asyncio.fixture(scope="package") +async def map_class_hash(account: BaseAccount) -> int: + contract = load_contract("Map") + class_hash, _ = await declare_cairo1_contract( + account, + contract["sierra"], + contract["casm"], + ) + return class_hash + + +@pytest_asyncio.fixture(scope="package", name="map_contract") +async def map_contract(account: BaseAccount, map_class_hash) -> Contract: + return await deploy_v1_contract( + account=account, + contract_name="Map", + class_hash=map_class_hash, + ) + + +@pytest_asyncio.fixture(scope="package") +async def map_abi() -> List: + contract = load_contract("Map") + compiled_contract = create_sierra_compiled_contract( + compiled_contract=contract["sierra"] + ) + assert compiled_contract.parsed_abi is not None + return compiled_contract.parsed_abi + + +@pytest.fixture(scope="package") +def map_compiled_contract_and_class_hash() -> Tuple[str, int]: + contract = load_contract("Map") + + return ( + contract["sierra"], + compute_casm_class_hash(create_casm_class(contract["casm"])), + ) + + +@pytest.fixture(scope="package") +def map_compiled_contract_casm() -> str: + contract = load_contract("Map") + + return contract["casm"] + + +@pytest_asyncio.fixture(scope="package") +async def simple_storage_with_event_class_hash(account: BaseAccount) -> int: + contract = load_contract("SimpleStorageWithEvent") + class_hash, _ = await declare_cairo1_contract( + account, contract["sierra"], contract["casm"] + ) + return class_hash + + +@pytest_asyncio.fixture(scope="function") +async def simple_storage_with_event_contract( + account: BaseAccount, + simple_storage_with_event_class_hash: int, +) -> Contract: + return await deploy_v1_contract( + account=account, + contract_name="SimpleStorageWithEvent", + class_hash=simple_storage_with_event_class_hash, + ) diff --git a/starknet_py/tests/e2e/mock/contracts/map.cairo b/starknet_py/tests/e2e/mock/contracts/map.cairo deleted file mode 100644 index 9d7ddc268..000000000 --- a/starknet_py/tests/e2e/mock/contracts/map.cairo +++ /dev/null @@ -1,25 +0,0 @@ -// Declare this file as a Starknet contract and set the required -// builtins. -%lang starknet -%builtins pedersen range_check - -from starkware.cairo.common.cairo_builtins import HashBuiltin - -// Define a storage variable. -@storage_var -func storage(key: felt) -> (value: felt) { -} - -@external -func put{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(key: felt, value: felt) { - storage.write(key, value); - return (); -} - -@view -func get{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(key: felt) -> ( - res: felt -) { - let (value) = storage.read(key); - return (value,); -} diff --git a/starknet_py/tests/e2e/mock/contracts/replace_class.cairo b/starknet_py/tests/e2e/mock/contracts/replace_class.cairo deleted file mode 100644 index f20dca5c7..000000000 --- a/starknet_py/tests/e2e/mock/contracts/replace_class.cairo +++ /dev/null @@ -1,11 +0,0 @@ -%lang starknet -%builtins pedersen range_check - -from starkware.cairo.common.cairo_builtins import HashBuiltin -from starkware.starknet.common.syscalls import replace_class - -@external -func replace_implementation{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*}(new_class: felt) { - replace_class(new_class); - return (); -} diff --git a/starknet_py/tests/e2e/mock/contracts/simple_storage_with_event.cairo b/starknet_py/tests/e2e/mock/contracts/simple_storage_with_event.cairo deleted file mode 100644 index bf612a8ec..000000000 --- a/starknet_py/tests/e2e/mock/contracts/simple_storage_with_event.cairo +++ /dev/null @@ -1,32 +0,0 @@ -%lang starknet -%builtins pedersen range_check - -from starkware.cairo.common.cairo_builtins import HashBuiltin - -@storage_var -func storage(key: felt) -> (value: felt) { -} - -@event -func put_called(key: felt, prev_value: felt, value: felt) { -} - -@event -func another_put_called(key: felt, prev_value: felt, value: felt, additional_value: felt) { -} - -@external -func put{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(key: felt, value: felt) { - let (prev_value) = storage.read(key); - put_called.emit(key=key, prev_value=prev_value, value=value); - storage.write(key, value); - return (); -} - -@external -func another_put{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(key: felt, value: felt) { - let (prev_value) = storage.read(key); - another_put_called.emit(key=key, prev_value=prev_value, value=value, additional_value=value); - storage.write(key, value); - return (); -} diff --git a/starknet_py/tests/e2e/mock/contracts_v1/src/erc20.cairo b/starknet_py/tests/e2e/mock/contracts_v1/src/erc20.cairo deleted file mode 100644 index 6deafcdcc..000000000 --- a/starknet_py/tests/e2e/mock/contracts_v1/src/erc20.cairo +++ /dev/null @@ -1,124 +0,0 @@ -#[contract] -mod ERC20 { - use zeroable::Zeroable; - use starknet::get_caller_address; - use starknet::contract_address_const; - use starknet::ContractAddress; - - struct Storage { - name: felt252, - symbol: felt252, - decimals: u8, - total_supply: u256, - balances: LegacyMap::, - allowances: LegacyMap::<(ContractAddress, ContractAddress), u256>, - } - - #[event] - fn Transfer(from: ContractAddress, to: ContractAddress, value: u256) {} - - #[event] - fn Approval(owner: ContractAddress, spender: ContractAddress, value: u256) {} - - #[constructor] - fn constructor( - name_: felt252, - symbol_: felt252, - decimals_: u8, - initial_supply: u256, - recipient: ContractAddress - ) { - name::write(name_); - symbol::write(symbol_); - decimals::write(decimals_); - assert(!recipient.is_zero(), 'ERC20: mint to the 0 address'); - total_supply::write(initial_supply); - balances::write(recipient, initial_supply); - Transfer(contract_address_const::<0>(), recipient, initial_supply); - } - - #[view] - fn get_name() -> felt252 { - name::read() - } - - #[view] - fn get_symbol() -> felt252 { - symbol::read() - } - - #[view] - fn get_decimals() -> u8 { - decimals::read() - } - - #[view] - fn get_total_supply() -> u256 { - total_supply::read() - } - - #[view] - fn balance_of(account: ContractAddress) -> u256 { - balances::read(account) - } - - #[view] - fn allowance(owner: ContractAddress, spender: ContractAddress) -> u256 { - allowances::read((owner, spender)) - } - - #[external] - fn transfer(recipient: ContractAddress, amount: u256) { - let sender = get_caller_address(); - transfer_helper(sender, recipient, amount); - } - - #[external] - fn transfer_from(sender: ContractAddress, recipient: ContractAddress, amount: u256) { - let caller = get_caller_address(); - spend_allowance(sender, caller, amount); - transfer_helper(sender, recipient, amount); - } - - #[external] - fn approve(spender: ContractAddress, amount: u256) { - let caller = get_caller_address(); - approve_helper(caller, spender, amount); - } - - #[external] - fn increase_allowance(spender: ContractAddress, added_value: u256) { - let caller = get_caller_address(); - approve_helper(caller, spender, allowances::read((caller, spender)) + added_value); - } - - #[external] - fn decrease_allowance(spender: ContractAddress, subtracted_value: u256) { - let caller = get_caller_address(); - approve_helper(caller, spender, allowances::read((caller, spender)) - subtracted_value); - } - - fn transfer_helper(sender: ContractAddress, recipient: ContractAddress, amount: u256) { - assert(!sender.is_zero(), 'ERC20: transfer from 0'); - assert(!recipient.is_zero(), 'ERC20: transfer to 0'); - balances::write(sender, balances::read(sender) - amount); - balances::write(recipient, balances::read(recipient) + amount); - Transfer(sender, recipient, amount); - } - - fn spend_allowance(owner: ContractAddress, spender: ContractAddress, amount: u256) { - let current_allowance = allowances::read((owner, spender)); - let ONES_MASK = 0xffffffffffffffffffffffffffffffff_u128; - let is_unlimited_allowance = current_allowance.low == ONES_MASK - & current_allowance.high == ONES_MASK; - if !is_unlimited_allowance { - approve_helper(owner, spender, current_allowance - amount); - } - } - - fn approve_helper(owner: ContractAddress, spender: ContractAddress, amount: u256) { - assert(!spender.is_zero(), 'ERC20: approve from 0'); - allowances::write((owner, spender), amount); - Approval(owner, spender, amount); - } -} diff --git a/starknet_py/tests/e2e/mock/contracts_v1/src/lib.cairo b/starknet_py/tests/e2e/mock/contracts_v1/src/lib.cairo index ad1f24f90..cb09f48dd 100644 --- a/starknet_py/tests/e2e/mock/contracts_v1/src/lib.cairo +++ b/starknet_py/tests/e2e/mock/contracts_v1/src/lib.cairo @@ -1,5 +1,4 @@ mod account; -mod erc20; mod hello_starknet; mod hello; mod minimal_contract; @@ -7,4 +6,4 @@ mod test_contract_declare; mod test_contract; mod test_enum; mod test_option; -mod token_bridge; +mod map; diff --git a/starknet_py/tests/e2e/mock/contracts_v1/src/map.cairo b/starknet_py/tests/e2e/mock/contracts_v1/src/map.cairo new file mode 100644 index 000000000..fa2947dd8 --- /dev/null +++ b/starknet_py/tests/e2e/mock/contracts_v1/src/map.cairo @@ -0,0 +1,16 @@ +#[contract] +mod Map { + struct Storage { + storage: LegacyMap::, + } + + #[external] + fn put(key: felt252, value: felt252) { + storage::write(key, value); + } + + #[external] + fn get(key: felt252) -> felt252 { + storage::read(key) + } +} diff --git a/starknet_py/tests/e2e/mock/contracts_v1/src/token_bridge.cairo b/starknet_py/tests/e2e/mock/contracts_v1/src/token_bridge.cairo deleted file mode 100644 index a76dc708e..000000000 --- a/starknet_py/tests/e2e/mock/contracts_v1/src/token_bridge.cairo +++ /dev/null @@ -1,161 +0,0 @@ -use starknet::ContractAddress; -use serde::Serde; -use traits::Into; -use zeroable::Zeroable; - -#[abi] -trait IMintableToken { - fn permissioned_mint(account: ContractAddress, amount: u256); - fn permissioned_burn(account: ContractAddress, amount: u256); -} - -#[contract] -mod TokenBridge { - use array::ArrayTrait; - use integer::Felt252IntoU256; - use integer::U128IntoFelt252; - use option::OptionTrait; - use serde::Serde; - use starknet::ContractAddress; - use starknet::contract_address::ContractAddressZeroable; - use starknet::get_caller_address; - use starknet::EthAddress; - use starknet::EthAddressIntoFelt252; - use starknet::EthAddressSerde; - use starknet::EthAddressZeroable; - use starknet::syscalls::send_message_to_l1_syscall; - use super::IMintableTokenDispatcher; - use super::IMintableTokenDispatcherTrait; - use super::IMintableTokenLibraryDispatcher; - use traits::Into; - use zeroable::Zeroable; - - - const WITHDRAW_MESSAGE: felt252 = 0; - const CONTRACT_IDENTITY: felt252 = 'STARKGATE'; - const CONTRACT_VERSION: felt252 = 2; - - struct Storage { - // The address of the L2 governor of this contract. Only the governor can set the other - // storage variables. - governor: ContractAddress, - // The L1 bridge address. Zero when unset. - l1_bridge: felt252, - // The L2 token contract address. Zero when unset. - l2_token: ContractAddress, - } - - // An event that is emitted when set_l1_bridge is called. - // * l1_bridge_address is the new l1 bridge address. - #[event] - fn l1_bridge_set(l1_bridge_address: EthAddress) {} - - // An event that is emitted when set_l2_token is called. - // * l2_token_address is the new l2 token address. - #[event] - fn l2_token_set(l2_token_address: ContractAddress) {} - - // An event that is emitted when initiate_withdraw is called. - // * l1_recipient is the l1 recipient address. - // * amount is the amount to withdraw. - // * caller_address is the address from which the call was made. - #[event] - fn withdraw_initiated( - l1_recipient: EthAddress, amount: u256, caller_address: ContractAddress - ) {} - - // An event that is emitted when handle_deposit is called. - // * account is the recipient address. - // * amount is the amount to deposit. - #[event] - fn deposit_handled(account: ContractAddress, amount: u256) {} - - #[view] - fn get_version() -> felt252 { - CONTRACT_VERSION - } - - #[view] - fn get_identity() -> felt252 { - CONTRACT_IDENTITY - } - - #[constructor] - fn constructor(governor_address: ContractAddress) { - assert(governor_address.is_non_zero(), 'ZERO_GOVERNOR_ADDRESS'); - governor::write(governor_address); - } - - #[external] - fn set_l1_bridge(l1_bridge_address: EthAddress) { - // The call is restricted to the governor. - assert(get_caller_address() == governor::read(), 'GOVERNOR_ONLY'); - - assert(l1_bridge::read().is_zero(), 'L1_BRIDGE_ALREADY_INITIALIZED'); - assert(l1_bridge_address.is_non_zero(), 'ZERO_BRIDGE_ADDRESS'); - - l1_bridge::write(l1_bridge_address.into()); - l1_bridge_set(l1_bridge_address); - } - - #[external] - fn set_l2_token(l2_token_address: ContractAddress) { - // The call is restricted to the governor. - assert(get_caller_address() == governor::read(), 'GOVERNOR_ONLY'); - - assert(l2_token::read().is_zero(), 'L2_TOKEN_ALREADY_INITIALIZED'); - assert(l2_token_address.is_non_zero(), 'ZERO_TOKEN_ADDRESS'); - - l2_token::write(l2_token_address); - l2_token_set(l2_token_address); - } - - #[external] - fn initiate_withdraw(l1_recipient: EthAddress, amount: u256) { - // Call burn on l2_token contract. - let caller_address = get_caller_address(); - IMintableTokenDispatcher { - contract_address: read_initialized_l2_token() - }.permissioned_burn(account: caller_address, :amount); - - // Send the message. - let mut message_payload: Array = ArrayTrait::new(); - message_payload.append(WITHDRAW_MESSAGE); - message_payload.append(l1_recipient.into()); - message_payload.append(amount.low.into()); - message_payload.append(amount.high.into()); - - send_message_to_l1_syscall( - to_address: read_initialized_l1_bridge(), payload: message_payload.span() - ); - withdraw_initiated(:l1_recipient, :amount, :caller_address); - } - - #[l1_handler] - fn handle_deposit(from_address: felt252, account: ContractAddress, amount: u256) { - assert(from_address == l1_bridge::read(), 'EXPECTED_FROM_BRIDGE_ONLY'); - - // Call mint on l2_token contract. - IMintableTokenDispatcher { - contract_address: read_initialized_l2_token() - }.permissioned_mint(:account, :amount); - - deposit_handled(:account, :amount); - } - - // Helpers (internal functions) - - // Read l1_bridge and verify it's initialized. - fn read_initialized_l1_bridge() -> felt252 { - let l1_bridge_address = l1_bridge::read(); - assert(l1_bridge_address.is_non_zero(), 'UNINITIALIZED_L1_BRIDGE_ADDRESS'); - l1_bridge_address - } - - // Read l2_token and verify it's initialized. - fn read_initialized_l2_token() -> ContractAddress { - let l2_token_address = l2_token::read(); - assert(l2_token_address.is_non_zero(), 'UNINITIALIZED_TOKEN'); - l2_token_address - } -} diff --git a/starknet_py/tests/e2e/mock/contracts_v2/src/lib.cairo b/starknet_py/tests/e2e/mock/contracts_v2/src/lib.cairo index db67477f0..486801326 100644 --- a/starknet_py/tests/e2e/mock/contracts_v2/src/lib.cairo +++ b/starknet_py/tests/e2e/mock/contracts_v2/src/lib.cairo @@ -11,3 +11,5 @@ mod test_enum; mod test_option; mod token_bridge; mod l1_l2; +mod map; +mod simple_storage_with_event; diff --git a/starknet_py/tests/e2e/mock/contracts_v2/src/map.cairo b/starknet_py/tests/e2e/mock/contracts_v2/src/map.cairo new file mode 100644 index 000000000..aa849d579 --- /dev/null +++ b/starknet_py/tests/e2e/mock/contracts_v2/src/map.cairo @@ -0,0 +1,25 @@ +#[starknet::interface] +trait IMap { + fn put(ref self: TMapState, key: felt252, value: felt252); + fn get(self: @TMapState, key: felt252) -> felt252; +} + + +#[starknet::contract] +mod Map { + #[storage] + struct Storage { + storage: LegacyMap::, + } + + #[abi(embed_v0)] + impl Map of super::IMap { + fn put(ref self: ContractState, key: felt252, value: felt252) { + self.storage.write(key, value); + } + + fn get(self: @ContractState, key: felt252) -> felt252 { + self.storage.read(key) + } + } +} diff --git a/starknet_py/tests/e2e/mock/contracts_v2/src/simple_storage_with_event.cairo b/starknet_py/tests/e2e/mock/contracts_v2/src/simple_storage_with_event.cairo new file mode 100644 index 000000000..f29bc8b0f --- /dev/null +++ b/starknet_py/tests/e2e/mock/contracts_v2/src/simple_storage_with_event.cairo @@ -0,0 +1,57 @@ +#[starknet::interface] +trait ISimpleStorageWithEvent { + fn put(ref self: TContractState, key: felt252, value: felt252); + fn another_put(ref self: TContractState, key: felt252, value: felt252); +} + +#[derive(Drop, Clone, starknet::Event)] +struct PutCalled { + key: felt252, + prev_value: felt252, + value: felt252, +} + +#[derive(Drop, Clone, starknet::Event)] +struct AnotherPutCalled { + key: felt252, + prev_value: felt252, + value: felt252, + additional_value: felt252, +} + +#[starknet::contract] +pub mod SimpleStorageWithEvent { + use super::{PutCalled, AnotherPutCalled}; + + #[storage] + struct Storage { + map: LegacyMap::, + } + + #[event] + #[derive(Drop, Clone, starknet::Event)] + pub enum Event { + PutCalled: PutCalled, + AnotherPutCalled: AnotherPutCalled, + } + + #[abi(embed_v0)] + impl SimpleStorag of super::ISimpleStorageWithEvent { + fn put(ref self: ContractState, key: felt252, value: felt252) { + let mut prev_value = self.map.read(key); + self.map.write(key, value); + self.emit(PutCalled { key: key, prev_value: prev_value, value: value }); + } + + fn another_put(ref self: ContractState, key: felt252, value: felt252) { + let mut prev_value = self.map.read(key); + self.map.write(key, value); + self + .emit( + AnotherPutCalled { + key: key, prev_value: prev_value, value: value, additional_value: value + } + ); + } + } +}