Self-Hosted EVM

close button

Part III


The stack is important, but since it does not fully support random-access, solely relying on it will result in a very inefficient machine. For this reason, the EVM also hosts memory, a non-persistent data space that can be accessed by index.

We will implement memory in contracts/libraries/Memory.sol.

Virtual Memory

For our nested EVM, we define a virtual memory zone as a contiguous array of bytes (see struct Memory) that, in reality, lives inside the real EVM's memory space. It will behave just like normal memory during the execution of a transaction.

It needs to support the following operations:

  • store and store8 to be able to write by blocks of 32 bytes and 1 byte respectively

  • load to read a 32-byte value

  • inject and extract that will be used to move data between real and virtual memory.

These operations, as we will later see, will be utilized by the EVM's subroutines.



init(uint256 maxSize)

Initializes a new instance of virtual memory with a maximum size of maxSize bytes

store(Memory memory, uint256 offset, bytes32 value)

Writes value at memory[offset:offset+0x20]

store8(Memory memory, uint256 offset, uint8 value)

Writes value at memory[offset:offset + 0x01]

load(Memory memory, uint256 offset)

Return `memory[offset:offset + 0x20]`

inject(Memory memory, uint256 src, uint256 dst, uint256 length)

Inject length bytes from real memory address src to virtualMem[dst:dst + length]

extract(Memory memory, uint256 length, uint256 offset)

Extract length bytes from memory[offset:offset + length]


Expected Message


sEVM: memory out of bounds

Your Task

Implement the functions in contracts/libraries/Memory.sol.

Run tests in Questplay

Then, one day, seeking a way in which the Weave might be free, the Great Archmage created the first Node Stone, ushering in the Age of Cryptomancy…