Skip to content

Commit 99720a4

Browse files
docs: add getting started guide for EEST opcode minilang (#1818)
Co-authored-by: danceratopz <[email protected]>
1 parent e88a211 commit 99720a4

File tree

1 file changed

+57
-8
lines changed

1 file changed

+57
-8
lines changed

docs/writing_tests/writing_a_new_test.md

Lines changed: 57 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -146,17 +146,66 @@ which allows checking for an exact `gas_used` value.
146146

147147
## Writing code for the accounts in the test
148148

149-
Account bytecode can be embedded in the test accounts by adding it to the `code`
150-
field of the `account` object, or the `data` field of the `tx` object if the
151-
bytecode is meant to be treated as init code or call data.
149+
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.
152150

153-
The code can be in either of the following formats:
151+
### Using the Python Opcode Minilang
154152

155-
- `bytes` object, representing the raw opcodes in binary format.
156-
- `str`, representing an hexadecimal format of the opcodes.
157-
- `Code` compilable object.
153+
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.
158154

159-
`Code` objects can be concatenated together by using the `+` operator.
155+
#### Example: Simple Addition Contract
156+
157+
```python
158+
from ethereum_test_vm.opcode import Opcodes
159+
160+
code = (
161+
Opcodes.PUSH1(0x02)
162+
+ Opcodes.PUSH1(0x03)
163+
+ Opcodes.ADD()
164+
+ Opcodes.PUSH1(0x00)
165+
+ Opcodes.SSTORE()
166+
+ Opcodes.STOP()
167+
)
168+
169+
# within a test function, using the "pre" fixture
170+
contract_address = pre.deploy_contract(code=code)
171+
```
172+
173+
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.
174+
175+
For a full list of available opcodes and their usage, see [`Opcodes`][ethereum_test_vm.Opcodes].
176+
177+
#### Higher-Level Constructs
178+
179+
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:
180+
181+
```python
182+
from ethereum_test_tools.code.generators import Switch, Case
183+
from ethereum_test_vm.opcode import Opcodes as Op
184+
185+
code = Switch(
186+
cases=[
187+
Case(condition=Op.EQ(Op.CALLDATALOAD(0), 1), action=Op.PUSH1(0x01) + Op.STOP()),
188+
Case(condition=Op.EQ(Op.CALLDATALOAD(0), 2), action=Op.PUSH1(0x02) + Op.STOP()),
189+
],
190+
default_action=Op.PUSH1(0x00) + Op.STOP(),
191+
)
192+
```
193+
194+
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].
195+
196+
#### Converting Bytecode to Minilang
197+
198+
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:
199+
200+
```console
201+
uv run evm_bytes hex-string 0x604260005260206000F3
202+
# ->
203+
# Op.PUSH1[0x42] + Op.PUSH1[0x0] + Op.MSTORE + Op.PUSH1[0x20] + Op.PUSH1[0x0] + Op.RETURN
204+
```
205+
206+
#### Restrictions: No Yul in Python Test Cases
207+
208+
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.
160209

161210
## Verifying the Accounts' Post States
162211

0 commit comments

Comments
 (0)