From eebde49bdb3cf21edd4c0238d872dfe788a6d8cc Mon Sep 17 00:00:00 2001 From: MozirDmitriy Date: Sun, 29 Jun 2025 22:15:27 +0300 Subject: [PATCH 1/9] Create eest_opcode_minilang.md --- docs/library/eest_opcode_minilang.md | 69 ++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 docs/library/eest_opcode_minilang.md diff --git a/docs/library/eest_opcode_minilang.md b/docs/library/eest_opcode_minilang.md new file mode 100644 index 00000000000..dc5071b2c41 --- /dev/null +++ b/docs/library/eest_opcode_minilang.md @@ -0,0 +1,69 @@ +# EEST Opcode Minilang + +This page helps test contributors get started with the EEST opcode minilang for writing smart contracts in execution-spec-tests. + +## Writing Smart Contracts Using the Opcodes Minilang + +The EEST project provides a Python-based minilang for constructing EVM bytecode using symbolic opcodes. This is implemented in [`Opcodes`](../../src/ethereum_test_vm/opcode.py), which contains all known EVM opcodes as Python enum members. Each opcode can be used as a callable to generate bytecode for tests. + +### Example: Simple Addition Contract + +```python +from ethereum_test_vm.opcode import Opcodes + +# This contract adds two numbers and stores the result in storage slot 0 +code = ( + Opcodes.PUSH1(0x02) # Push 2 + + Opcodes.PUSH1(0x03) # Push 3 + + Opcodes.ADD() # Add + + Opcodes.PUSH1(0x00) # Storage slot 0 + + Opcodes.SSTORE() # Store result + + Opcodes.STOP() +) +``` + +You can assign this `code` to the `code` field of an account in your test's `pre` or `post` state. + +For a full list of available opcodes and their usage, see [`src/ethereum_test_vm/opcode.py`](../../src/ethereum_test_vm/opcode.py). + +## Higher-Level Constructs + +To help with more complex control flow, EEST provides higher-level constructs in [`Switch`](../../src/ethereum_test_tools/code/generators.py) and related helpers. + +### Example: Switch-Case + +```python +from ethereum_test_tools.code.generators import Switch, Case +from ethereum_test_vm.opcode import Opcodes as Op + +# Example: Switch on calldata value +code = Switch( + cases=[ + Case(condition=Op.EQ(Op.CALLDATALOAD(0), 1), action=Op.PUSH1(0x01) + Op.STOP()), + Case(condition=Op.EQ(Op.CALLDATALOAD(0), 2), action=Op.PUSH1(0x02) + Op.STOP()), + ], + default_action=Op.PUSH1(0x00) + Op.STOP(), +) +``` + +See [`src/ethereum_test_tools/code/generators.py`](../../src/ethereum_test_tools/code/generators.py) for more details and additional constructs like `While` and `Conditional`. + +## Converting Bytecode to Minilang + +If you have EVM bytecode (as hex or binary), you can use the [`evm_bytes` CLI tool](./cli/evm_bytes.md) to convert it to the EEST Python opcode minilang automatically: + +- [evm_bytes CLI documentation](./cli/evm_bytes.md) +- [Online reference](https://eest.ethereum.org/main/library/cli/evm_bytes/) + +## Restrictions: No Yul in Python Test Cases + +**Note:** As of [PR #1779](https://github.com/ethereum/execution-spec-tests/pull/1779), the use of Yul source in Python test cases is forbidden. All new tests must use the Python opcode minilang as shown above. + +For more on writing code for accounts in tests, see [Writing a New Test: Writing code for the accounts in the test](../writing_tests/writing_a_new_test.md#writing-code-for-the-accounts-in-the-test). + +## See Also +- [Opcodes enum source](../../src/ethereum_test_vm/opcode.py) +- [Switch and higher-level constructs](../../src/ethereum_test_tools/code/generators.py) +- [evm_bytes CLI](./cli/evm_bytes.md) +- [Writing code for the accounts in the test](../writing_tests/writing_a_new_test.md#writing-code-for-the-accounts-in-the-test) +- [No Yul in Python tests (PR #1779)](https://github.com/ethereum/execution-spec-tests/pull/1779) From 1d047ad8297401fae754538e9181948c89e21951 Mon Sep 17 00:00:00 2001 From: MozirDmitriy Date: Sun, 29 Jun 2025 22:22:05 +0300 Subject: [PATCH 2/9] Update index.md --- docs/library/index.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/library/index.md b/docs/library/index.md index de5b5183f1e..4381af15c5c 100644 --- a/docs/library/index.md +++ b/docs/library/index.md @@ -11,4 +11,5 @@ Execution spec tests consists of several packages that implement helper classes - [`ethereum_test_types`](./ethereum_test_types.md) - provides Ethereum types built on top of the base types which are used to define test cases and interact with other libraries. - [`ethereum_test_vm`](./ethereum_test_vm.md) - provides definitions for the Ethereum Virtual Machine (EVM) as used to define bytecode in test cases. - [`ethereum_clis`](./ethereum_clis.md) - a wrapper for the transition (`t8n`) tool. +- [`eest_opcode_minilang`](./eest_opcode_minilang.md) - how to write smart contracts using the EEST Opcodes minilang, including available higher-level constructs and CLI tools. - [`pytest_plugins`](./pytest_plugins/index.md) - contains pytest customizations that provide additional functionality for generating test fixtures. From 699d23acd6468945adda0d9cacf6c8df15fce962 Mon Sep 17 00:00:00 2001 From: MozirDmitriy Date: Mon, 30 Jun 2025 22:35:08 +0300 Subject: [PATCH 3/9] Delete docs/library/eest_opcode_minilang.md --- docs/library/eest_opcode_minilang.md | 69 ---------------------------- 1 file changed, 69 deletions(-) delete mode 100644 docs/library/eest_opcode_minilang.md diff --git a/docs/library/eest_opcode_minilang.md b/docs/library/eest_opcode_minilang.md deleted file mode 100644 index dc5071b2c41..00000000000 --- a/docs/library/eest_opcode_minilang.md +++ /dev/null @@ -1,69 +0,0 @@ -# EEST Opcode Minilang - -This page helps test contributors get started with the EEST opcode minilang for writing smart contracts in execution-spec-tests. - -## Writing Smart Contracts Using the Opcodes Minilang - -The EEST project provides a Python-based minilang for constructing EVM bytecode using symbolic opcodes. This is implemented in [`Opcodes`](../../src/ethereum_test_vm/opcode.py), which contains all known EVM opcodes as Python enum members. Each opcode can be used as a callable to generate bytecode for tests. - -### Example: Simple Addition Contract - -```python -from ethereum_test_vm.opcode import Opcodes - -# This contract adds two numbers and stores the result in storage slot 0 -code = ( - Opcodes.PUSH1(0x02) # Push 2 - + Opcodes.PUSH1(0x03) # Push 3 - + Opcodes.ADD() # Add - + Opcodes.PUSH1(0x00) # Storage slot 0 - + Opcodes.SSTORE() # Store result - + Opcodes.STOP() -) -``` - -You can assign this `code` to the `code` field of an account in your test's `pre` or `post` state. - -For a full list of available opcodes and their usage, see [`src/ethereum_test_vm/opcode.py`](../../src/ethereum_test_vm/opcode.py). - -## Higher-Level Constructs - -To help with more complex control flow, EEST provides higher-level constructs in [`Switch`](../../src/ethereum_test_tools/code/generators.py) and related helpers. - -### Example: Switch-Case - -```python -from ethereum_test_tools.code.generators import Switch, Case -from ethereum_test_vm.opcode import Opcodes as Op - -# Example: Switch on calldata value -code = Switch( - cases=[ - Case(condition=Op.EQ(Op.CALLDATALOAD(0), 1), action=Op.PUSH1(0x01) + Op.STOP()), - Case(condition=Op.EQ(Op.CALLDATALOAD(0), 2), action=Op.PUSH1(0x02) + Op.STOP()), - ], - default_action=Op.PUSH1(0x00) + Op.STOP(), -) -``` - -See [`src/ethereum_test_tools/code/generators.py`](../../src/ethereum_test_tools/code/generators.py) for more details and additional constructs like `While` and `Conditional`. - -## Converting Bytecode to Minilang - -If you have EVM bytecode (as hex or binary), you can use the [`evm_bytes` CLI tool](./cli/evm_bytes.md) to convert it to the EEST Python opcode minilang automatically: - -- [evm_bytes CLI documentation](./cli/evm_bytes.md) -- [Online reference](https://eest.ethereum.org/main/library/cli/evm_bytes/) - -## Restrictions: No Yul in Python Test Cases - -**Note:** As of [PR #1779](https://github.com/ethereum/execution-spec-tests/pull/1779), the use of Yul source in Python test cases is forbidden. All new tests must use the Python opcode minilang as shown above. - -For more on writing code for accounts in tests, see [Writing a New Test: Writing code for the accounts in the test](../writing_tests/writing_a_new_test.md#writing-code-for-the-accounts-in-the-test). - -## See Also -- [Opcodes enum source](../../src/ethereum_test_vm/opcode.py) -- [Switch and higher-level constructs](../../src/ethereum_test_tools/code/generators.py) -- [evm_bytes CLI](./cli/evm_bytes.md) -- [Writing code for the accounts in the test](../writing_tests/writing_a_new_test.md#writing-code-for-the-accounts-in-the-test) -- [No Yul in Python tests (PR #1779)](https://github.com/ethereum/execution-spec-tests/pull/1779) From 730e69cd8b2bfbbfcf06c1b535ff499493373fc9 Mon Sep 17 00:00:00 2001 From: MozirDmitriy Date: Mon, 30 Jun 2025 22:35:41 +0300 Subject: [PATCH 4/9] Update writing_a_new_test.md --- docs/writing_tests/writing_a_new_test.md | 55 ++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 4 deletions(-) diff --git a/docs/writing_tests/writing_a_new_test.md b/docs/writing_tests/writing_a_new_test.md index 2ebd83a7699..859796e434a 100644 --- a/docs/writing_tests/writing_a_new_test.md +++ b/docs/writing_tests/writing_a_new_test.md @@ -154,13 +154,60 @@ The code can be in either of the following formats: - `bytes` object, representing the raw opcodes in binary format. - `str`, representing an hexadecimal format of the opcodes. -- `Code` compilable object. +- `Code` compilable object (see below for supported types). -Currently supported built-in compilable objects are: +### Using the Python Opcode Minilang (RECOMMENDED) -- `Yul` object containing [Yul source code](https://docs.soliditylang.org/en/latest/yul.html). +The recommended way to write EVM bytecode for tests is to use the Python-based minilang provided by the `Opcodes` class in [`src/ethereum_test_vm/opcode.py`](../../src/ethereum_test_vm/opcode.py). This allows you to construct bytecode using symbolic opcodes as Python objects. -`Code` objects can be concatenated together by using the `+` operator. +#### Example: Simple Addition Contract + +```python +from ethereum_test_vm.opcode import Opcodes + +code = ( + Opcodes.PUSH1(0x02) + + Opcodes.PUSH1(0x03) + + Opcodes.ADD() + + Opcodes.PUSH1(0x00) + + Opcodes.SSTORE() + + Opcodes.STOP() +) +``` + +You can assign this `code` to the `code` field of an account in your test's `pre` or `post` state. + +For a full list of available opcodes and their usage, see [`src/ethereum_test_vm/opcode.py`](../../src/ethereum_test_vm/opcode.py). + +### Higher-Level Constructs + +For more complex control flow, you can use constructs like `Switch` and `Case` from [`src/ethereum_test_tools/code/generators.py`](../../src/ethereum_test_tools/code/generators.py): + +```python +from ethereum_test_tools.code.generators import Switch, Case +from ethereum_test_vm.opcode import Opcodes as Op + +code = Switch( + cases=[ + Case(condition=Op.EQ(Op.CALLDATALOAD(0), 1), action=Op.PUSH1(0x01) + Op.STOP()), + Case(condition=Op.EQ(Op.CALLDATALOAD(0), 2), action=Op.PUSH1(0x02) + Op.STOP()), + ], + default_action=Op.PUSH1(0x00) + Op.STOP(), +) +``` + +See [`src/ethereum_test_tools/code/generators.py`](../../src/ethereum_test_tools/code/generators.py) for more details and additional constructs like `While` and `Conditional`. + +### Converting Bytecode to Minilang + +If you have EVM bytecode (as hex or binary), you can use the [`evm_bytes` CLI tool](../library/cli/evm_bytes.md) to convert it to the EEST Python opcode minilang automatically: + +- [evm_bytes CLI documentation](../library/cli/evm_bytes.md) +- [Online reference](https://eest.ethereum.org/main/library/cli/evm_bytes/) + +### Restrictions: No Yul in Python Test Cases + +**Note:** As of [PR #1779](https://github.com/ethereum/execution-spec-tests/pull/1779), the use of Yul source in Python test cases is forbidden. All new tests must use the Python opcode minilang as shown above. ## Verifying the Accounts' Post States From 6e1e21d06aa64a707d0c0178b39f614f335d4db2 Mon Sep 17 00:00:00 2001 From: MozirDmitriy Date: Mon, 30 Jun 2025 22:36:14 +0300 Subject: [PATCH 5/9] Update index.md --- docs/library/index.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/library/index.md b/docs/library/index.md index 4381af15c5c..de5b5183f1e 100644 --- a/docs/library/index.md +++ b/docs/library/index.md @@ -11,5 +11,4 @@ Execution spec tests consists of several packages that implement helper classes - [`ethereum_test_types`](./ethereum_test_types.md) - provides Ethereum types built on top of the base types which are used to define test cases and interact with other libraries. - [`ethereum_test_vm`](./ethereum_test_vm.md) - provides definitions for the Ethereum Virtual Machine (EVM) as used to define bytecode in test cases. - [`ethereum_clis`](./ethereum_clis.md) - a wrapper for the transition (`t8n`) tool. -- [`eest_opcode_minilang`](./eest_opcode_minilang.md) - how to write smart contracts using the EEST Opcodes minilang, including available higher-level constructs and CLI tools. - [`pytest_plugins`](./pytest_plugins/index.md) - contains pytest customizations that provide additional functionality for generating test fixtures. From 88801519db31acdf3c5f561dec64481aa3b0979b Mon Sep 17 00:00:00 2001 From: MozirDmitriy Date: Fri, 4 Jul 2025 17:45:27 +0300 Subject: [PATCH 6/9] Update writing_a_new_test.md --- docs/writing_tests/writing_a_new_test.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/writing_tests/writing_a_new_test.md b/docs/writing_tests/writing_a_new_test.md index 859796e434a..21eb2e1b799 100644 --- a/docs/writing_tests/writing_a_new_test.md +++ b/docs/writing_tests/writing_a_new_test.md @@ -158,7 +158,7 @@ The code can be in either of the following formats: ### Using the Python Opcode Minilang (RECOMMENDED) -The recommended way to write EVM bytecode for tests is to use the Python-based minilang provided by the `Opcodes` class in [`src/ethereum_test_vm/opcode.py`](../../src/ethereum_test_vm/opcode.py). This allows you to construct bytecode using symbolic opcodes as Python objects. +The recommended way to write EVM bytecode for tests is to use the Python-based minilang provided by the [Opcodes][ethereum_test_vm.opcode.Opcodes] class. This allows you to construct bytecode using symbolic opcodes as Python objects. #### Example: Simple Addition Contract @@ -177,11 +177,11 @@ code = ( You can assign this `code` to the `code` field of an account in your test's `pre` or `post` state. -For a full list of available opcodes and their usage, see [`src/ethereum_test_vm/opcode.py`](../../src/ethereum_test_vm/opcode.py). +For a full list of available opcodes and their usage, see the [Opcodes][ethereum_test_vm.opcode.Opcodes] reference. ### Higher-Level Constructs -For more complex control flow, you can use constructs like `Switch` and `Case` from [`src/ethereum_test_tools/code/generators.py`](../../src/ethereum_test_tools/code/generators.py): +For more complex control flow, you can use constructs like [Switch][ethereum_test_tools.code.generators.Switch] and [Case][ethereum_test_tools.code.generators.Case] from the [ethereum_test_tools.code.generators][ethereum_test_tools.code.generators] module: ```python from ethereum_test_tools.code.generators import Switch, Case @@ -196,7 +196,7 @@ code = Switch( ) ``` -See [`src/ethereum_test_tools/code/generators.py`](../../src/ethereum_test_tools/code/generators.py) for more details and additional constructs like `While` and `Conditional`. +See the [ethereum_test_tools.code.generators][ethereum_test_tools.code.generators] reference for more details and additional constructs like [While][ethereum_test_tools.code.generators.While] and [Conditional][ethereum_test_tools.code.generators.Conditional]. ### Converting Bytecode to Minilang From 5d7365b16b74f057b74d6525213620829df298c4 Mon Sep 17 00:00:00 2001 From: danceratopz Date: Mon, 7 Jul 2025 17:13:49 +0200 Subject: [PATCH 7/9] Apply suggestions from code review --- docs/writing_tests/writing_a_new_test.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/writing_tests/writing_a_new_test.md b/docs/writing_tests/writing_a_new_test.md index 387f4cc1a49..8221a55e71a 100644 --- a/docs/writing_tests/writing_a_new_test.md +++ b/docs/writing_tests/writing_a_new_test.md @@ -160,7 +160,7 @@ The code can be in either of the following formats: ### Using the Python Opcode Minilang (RECOMMENDED) -The recommended way to write EVM bytecode for tests is to use the Python-based minilang provided by the [Opcodes][ethereum_test_vm.opcode.Opcodes] class. This allows you to construct bytecode using symbolic opcodes as Python objects. +EVM bytecode for tests should be written using the Python-based minilang provided by the [Opcodes][ethereum_test_vm.opcode.Opcodes] class. This allows you to construct bytecode using symbolic opcodes as Python objects. #### Example: Simple Addition Contract @@ -183,7 +183,7 @@ For a full list of available opcodes and their usage, see the [Opcodes][ethereum ### Higher-Level Constructs -For more complex control flow, you can use constructs like [Switch][ethereum_test_tools.code.generators.Switch] and [Case][ethereum_test_tools.code.generators.Case] from the [ethereum_test_tools.code.generators][ethereum_test_tools.code.generators] module: +For more complex control flow, you can use constructs like [Switch][ethereum_test_tools.code.generators.Switch] and [Case][ethereum_test_tools.code.generators.Case] from the `ethereum_test_tools.code.generators` module: ```python from ethereum_test_tools.code.generators import Switch, Case @@ -198,7 +198,7 @@ code = Switch( ) ``` -See the [ethereum_test_tools.code.generators][ethereum_test_tools.code.generators] reference for more details and additional constructs like [While][ethereum_test_tools.code.generators.While] and [Conditional][ethereum_test_tools.code.generators.Conditional]. +The `ethereum_test_tools.code.generators` module also defines other high-level constructs like [While][ethereum_test_tools.code.generators.While] and [Conditional][ethereum_test_tools.code.generators.Conditional]. ### Converting Bytecode to Minilang @@ -209,7 +209,7 @@ If you have EVM bytecode (as hex or binary), you can use the [`evm_bytes` CLI to ### Restrictions: No Yul in Python Test Cases -**Note:** As of [PR #1779](https://github.com/ethereum/execution-spec-tests/pull/1779), the use of Yul source in Python test cases is forbidden. All new tests must use the Python opcode minilang as shown above. +As of [PR #1779](https://github.com/ethereum/execution-spec-tests/pull/1779), the use of Yul source in Python test cases is forbidden. All new tests must use the Python opcode minilang as shown above. ## Verifying the Accounts' Post States From 7907fbca4d10a1d1e7d7ee302e55d88359b9b56e Mon Sep 17 00:00:00 2001 From: MozirDmitriy Date: Mon, 7 Jul 2025 18:22:28 +0300 Subject: [PATCH 8/9] Update docs/writing_tests/writing_a_new_test.md Co-authored-by: danceratopz --- docs/writing_tests/writing_a_new_test.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/docs/writing_tests/writing_a_new_test.md b/docs/writing_tests/writing_a_new_test.md index 8221a55e71a..57e4bce2f21 100644 --- a/docs/writing_tests/writing_a_new_test.md +++ b/docs/writing_tests/writing_a_new_test.md @@ -204,9 +204,6 @@ The `ethereum_test_tools.code.generators` module also defines other high-level c If you have EVM bytecode (as hex or binary), you can use the [`evm_bytes` CLI tool](../library/cli/evm_bytes.md) to convert it to the EEST Python opcode minilang automatically: -- [evm_bytes CLI documentation](../library/cli/evm_bytes.md) -- [Online reference](https://eest.ethereum.org/main/library/cli/evm_bytes/) - ### Restrictions: No Yul in Python Test Cases As of [PR #1779](https://github.com/ethereum/execution-spec-tests/pull/1779), the use of Yul source in Python test cases is forbidden. All new tests must use the Python opcode minilang as shown above. From 5f4f802fd780ba7600b55c610755732376052f98 Mon Sep 17 00:00:00 2001 From: danceratopz Date: Mon, 7 Jul 2025 17:42:53 +0200 Subject: [PATCH 9/9] docs: misc changes --- docs/writing_tests/writing_a_new_test.md | 41 ++++++++++++------------ 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/docs/writing_tests/writing_a_new_test.md b/docs/writing_tests/writing_a_new_test.md index 57e4bce2f21..89e4197b902 100644 --- a/docs/writing_tests/writing_a_new_test.md +++ b/docs/writing_tests/writing_a_new_test.md @@ -146,21 +146,11 @@ which allows checking for an exact `gas_used` value. ## Writing code for the accounts in the test -Account bytecode can be embedded in the test accounts by adding it to the `code` -field of the `account` object, or the `data` field of the `tx` object if the -bytecode is meant to be treated as init code or call data. +Account bytecode can be "deployed" in a test's pre-state using the `pre` pytest fixture. The @ethereum/execution-spec-tests Python [`Opcodes`][ethereum_test_vm.Opcodes] minilang can be used to help write the bytecode in a readable form. -The code can be in either of the following formats: +### Using the Python Opcode Minilang -- `bytes` object, representing the raw opcodes in binary format. -- `str`, representing an hexadecimal format of the opcodes. -- `Code` compilable object (see below for supported types). - -`Code` objects can be concatenated together by using the `+` operator. - -### Using the Python Opcode Minilang (RECOMMENDED) - -EVM bytecode for tests should be written using the Python-based minilang provided by the [Opcodes][ethereum_test_vm.opcode.Opcodes] class. This allows you to construct bytecode using symbolic opcodes as Python objects. +EVM bytecode for tests should be written using the Python-based minilang provided by the [`Opcodes`][ethereum_test_vm.Opcodes] class. This allows you to construct bytecode using symbolic opcodes as Python objects. #### Example: Simple Addition Contract @@ -175,15 +165,18 @@ code = ( + Opcodes.SSTORE() + Opcodes.STOP() ) + +# within a test function, using the "pre" fixture +contract_address = pre.deploy_contract(code=code) ``` -You can assign this `code` to the `code` field of an account in your test's `pre` or `post` state. +You add this contract to the test's pre-state using the `pre` fixture or assign this `code` to the `code` field of an account in your test's `post` state. See the [state test tutorial](./tutorials/state_transition.md) for more help. -For a full list of available opcodes and their usage, see the [Opcodes][ethereum_test_vm.opcode.Opcodes] reference. +For a full list of available opcodes and their usage, see [`Opcodes`][ethereum_test_vm.Opcodes]. -### Higher-Level Constructs +#### Higher-Level Constructs -For more complex control flow, you can use constructs like [Switch][ethereum_test_tools.code.generators.Switch] and [Case][ethereum_test_tools.code.generators.Case] from the `ethereum_test_tools.code.generators` module: +For more complex control flow, you can use constructs like [`Switch`][ethereum_test_tools.code.generators.Switch] and [`Case`][ethereum_test_tools.code.generators.Case] from the `ethereum_test_tools.code.generators` module: ```python from ethereum_test_tools.code.generators import Switch, Case @@ -198,13 +191,19 @@ code = Switch( ) ``` -The `ethereum_test_tools.code.generators` module also defines other high-level constructs like [While][ethereum_test_tools.code.generators.While] and [Conditional][ethereum_test_tools.code.generators.Conditional]. +The `ethereum_test_tools.code.generators` module also defines other high-level constructs like [`While`][ethereum_test_tools.code.generators.While] and [`Conditional`][ethereum_test_tools.code.generators.Conditional]. + +#### Converting Bytecode to Minilang -### Converting Bytecode to Minilang +If you have EVM bytecode (as hex or binary), you can use the [`evm_bytes` CLI tool](../library/cli/evm_bytes.md) to convert it to the EEST Python opcode minilang automatically, for example: -If you have EVM bytecode (as hex or binary), you can use the [`evm_bytes` CLI tool](../library/cli/evm_bytes.md) to convert it to the EEST Python opcode minilang automatically: +```console +uv run evm_bytes hex-string 0x604260005260206000F3 +# -> +# Op.PUSH1[0x42] + Op.PUSH1[0x0] + Op.MSTORE + Op.PUSH1[0x20] + Op.PUSH1[0x0] + Op.RETURN +``` -### Restrictions: No Yul in Python Test Cases +#### Restrictions: No Yul in Python Test Cases As of [PR #1779](https://github.com/ethereum/execution-spec-tests/pull/1779), the use of Yul source in Python test cases is forbidden. All new tests must use the Python opcode minilang as shown above.