Skip to main content

smol-evm

👨‍🔬 An extensible Python implementation of the Ethereum yellow paper from scratch.

Write-up with examples:

Building an EVM from scratch [karmacoma.notion.so]

Getting started

Install smol-evm

pip install smol-evm

Run the CLI

$ smol-evm --help
Usage: smol-evm [OPTIONS] COMMAND [ARGS]...

Options:
  --debug / --no-debug
  --help                Show this message and exit.

Commands:
  disassemble  Disassembles the given bytecode
  run          Creates an EVM execution context and runs the given bytecode

$ smol-evm run

Execute bytecode

$ smol-evm run --code 602a6000526001601ff3 --no-trace
0x2a

Disassemble bytecode

$ smol-evm disassemble --code 602a6000526001601ff3
0000: PUSH1 0x2a
0002: PUSH1 0x00
0004: MSTORE
0005: PUSH1 0x01
0007: PUSH1 0x1f
0009: RETURN

Assemble bytecode

smol-evm disassemble --code 602a6000526001601ff3 | smol-evm assemble -
602a6000526001601ff3

Use as a library

⚠️ the interface is very much not stable and is subject to frequent changes

python
>>> from smol_evm.opcodes import *
>>> code = assemble([PC, DUP1, MSTORE])
588052

Developer mode

Install Poetry

curl -sSL https://install.python-poetry.org | python3 -

Install Dependencies

poetry install

Run Tests

poetry run pytest -v

Run the black code formatter

poetry run black src

Misc scripts

raw_deployer.py

Takes the binary representation of a contract and generates the init code that will deploy that contract (Ti in Yellow Paper terminology).

For instance, let's say that you have some Yul code, that when compiled with solc has the following binary representation: 602a60205260206020f3.

> python raw_deployer.py 602a60205260206020f3
600a8061000d6000396000f3fe602a60205260206020f3

You can now deploy this code:

web3.eth.sendTransaction({
    from: /* your address */,
    /* no to address as we are creating a contract */
    data: "600a8061000d6000396000f3fe602a60205260206020f3"
})

Wait for the transaction to be confirmed, and go look at the code of the contract that was deployed, it should match our compiled Yul code 602a60205260206020f3 🙌

create2.py

Based on web3.py, this script can find addresses of contracts deployed by the CREATE2 opcode that satisfy a particular predicate.

Usage: python3 create2.py deployer_addr <salt | predicate> bytecode

When passing a salt value, this script prints the address of the newly deployed contract based on the deployer address and bytecode hash.

Example: python3 create2.py Bf6cE3350513EfDcC0d5bd5413F1dE53D0E4f9aE 42 602a60205260206020f3

When passing a predicate, this script will search for a salt value such that the new address satisfies the predicate.

Example: python3 create2.py Bf6cE3350513EfDcC0d5bd5413F1dE53D0E4f9aE 'lambda addr: "badc0de" in addr.lower()' 602a60205260206020f3

Another predicate that may be useful: 'lambda addr: addr.startswith("0" * 8)'

Use with a deployer contract like this:

contract Deployer {
    function deploy(bytes memory code, uint256 salt) public returns(address) {
        address addr;
        assembly {
          addr := create2(0, add(code, 0x20), mload(code), salt)
          if iszero(extcodesize(addr)) {
            revert(0, 0)
          }
        }

        return addr;
    }
}

Metadata

Release files for smol-evm 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for smol-evm 0.1.0
File Size Uploaded Provenance Actions
smol_evm-0.1.0.tar.gz 13.5 kB Without provenance Details for smol_evm-0.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for smol-evm 0.1.0
File Interpreter ABI Platform Actions
smol_evm-0.1.0-py3-none-any.whl Python 3 none any Details for smol_evm-0.1.0-py3-none-any.whl

Total release size: 27.2 kB

Release files / smol_evm-0.1.0.tar.gz

Download URL smol_evm-0.1.0.tar.gz
Size 13.5 kB
Tags Source
SHA-256 checksum
How to use checksums
92676cf84d640abe564316ef6118690ad519880796c4254c069de7931a723333
BLAKE2b-256 checksum
How to use checksums
8c0c596f7e720460b33c2301c8a490460730246f335427ea43edbdf4fad6202f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.3.2 CPython/3.10.9 Darwin/22.3.0

Release files / smol_evm-0.1.0-py3-none-any.whl

Download URL smol_evm-0.1.0-py3-none-any.whl
Size 13.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c012f534ef53b6ddf225d235edd2148f0399f601c80e4c2f6c805b5fe5bd12b8
BLAKE2b-256 checksum
How to use checksums
9f24995b6c7f7224afdd2ab6d08774ac34d22a033ae00f8da3a0b8ccfdd942db
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.3.2 CPython/3.10.9 Darwin/22.3.0

Security for smol-evm 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page