Skip to content

test_extcodehash_empty_contract_creation()

Documentation for tests/constantinople/eip1052_extcodehash/test_extcodehash.py::test_extcodehash_empty_contract_creation@ffe48572.

Generate fixtures for these test cases for Bogota with:

fill -v tests/constantinople/eip1052_extcodehash/test_extcodehash.py::test_extcodehash_empty_contract_creation --fork Bogota

Test EXTCODEHASH/EXTCODESIZE for empty contracts created with CREATE/CREATE2.

Source code in tests/constantinople/eip1052_extcodehash/test_extcodehash.py
@pytest.mark.ported_from(
    [
        "https://github.com/ethereum/tests/blob/v13.3/src/GeneralStateTestsFiller/stExtCodeHash/extcodehashEmpty_ParisFiller.yml",  # noqa: E501
    ],
    pr=["https://github.com/ethereum/execution-specs/pull/2237"],
)
@pytest.mark.parametrize("opcode", [Op.CREATE, Op.CREATE2])
def test_extcodehash_empty_contract_creation(
    state_test: StateTestFiller,
    pre: Alloc,
    opcode: Op,
) -> None:
    """
    Test EXTCODEHASH/EXTCODESIZE for empty contracts created with
    CREATE/CREATE2.
    """
    storage = Storage()
    initcode = Op.RETURN(0, 0)
    expected_hash = keccak256(b"")

    created_slot = storage.store_next(0)
    hash_slot = storage.store_next(expected_hash)
    size_slot = storage.store_next(0)
    copy_slot = storage.store_next(0)

    create_op = (
        opcode(value=0, offset=0, size=len(initcode), salt=0)
        if opcode == Op.CREATE2
        else opcode(value=0, offset=0, size=len(initcode))
    )

    code = (
        Op.MSTORE(0, Op.PUSH32(bytes(initcode).ljust(32, b"\0")))
        + Op.SSTORE(created_slot, create_op)
        + Op.SSTORE(
            hash_slot,
            Op.EXTCODEHASH(Op.SLOAD(created_slot)),
        )
        + Op.SSTORE(
            size_slot,
            Op.EXTCODESIZE(Op.SLOAD(created_slot)),
        )
        + Op.EXTCODECOPY(Op.SLOAD(created_slot), 0, 0, 32)
        + Op.SSTORE(copy_slot, Op.MLOAD(0))
        + Op.STOP
    )

    code_address = pre.deploy_contract(code, storage=storage.canary())
    created_address = (
        compute_create2_address(
            address=code_address,
            salt=0,
            initcode=initcode,
        )
        if opcode == Op.CREATE2
        else compute_create_address(address=code_address, nonce=1)
    )
    storage[created_slot] = created_address

    tx = Transaction(sender=pre.fund_eoa(), to=code_address)

    state_test(
        pre=pre,
        post={
            code_address: Account(storage=storage),
            created_address: Account(nonce=1, code=b""),
        },
        tx=tx,
    )

Parametrized Test Cases

This test generates 2 parametrized test cases across 11 forks.