A rudimentary implementation of the Ethereum Virtual Machine in Typescript /ti:vi:εm/.
- The EVM is a stack-based computer, responsible for the execution of smart contract instructions.
- Tiviem implements all instructions defined in the Shanghai hardfork.
- Given some bytecode and an execution context with the relevant state values setup, Tiviem will step through the bytecode and execute each of the instructions and apply the state changes.
- Tiviem is composed of a simple call stack, a bytecode interpreter, the execution context and implementations of each of the instructions.
- The call stack is implemented as an array of bigints, Uint8Array is used for memory and bytecode, while a Map is used to represent storage, world-state.
- All opcodes share a standard interface for passing argument, resulting in consistent and predictable code. (See
opcodes.ts
) - A CLI is provided for experimentation with arbitrary bytecode. For more control, a custom execution context can be passed into the
evm()
function.
Example usage:
$ bun run cli.ts --code 6001600202 --verbose 2
verbose
orv
: sets verbosity level for trace. Options: 0, 1, 2, 3.code
orc
: flag to provide the bytecode to execute. (required)tx
: flag to provide transaction details. (see definiton ofTransaction
interface)
export interface Context {
address: bigint, // address of the contract being called in current tx
caller: bigint, // address of the caller
origin: bigint, // address of the call origin
gasPrice: bigint, // current gas price, used in the respective opcode
gasLeft: number,
isStatic: boolean, // weather or not the current call is allowed to perform a state change
callValue: bigint, // ether passed in current call
callData: Uint8Array // hex data passed in current call
bytecode: Uint8Array, // bytecode of contract being called
block: Block,
state: Map<bigint, AccountState>, // set the state up
}
- When calling
evm(context, verbosity);
you must provide it with the above information about the current call.
This year I had planned to dive deep into the Ethereum core and what better way than to rebuild (a part of) it.
- See blog post for reasoning on some technical decisions I made.
- I've attempted to write fairly functional-style code, I deviate in places where I had to wack my head against my keyboard.
- If you're planning on building an EVM I've left some resources below. Feel free to contact me (twitter/warpcast)
- Gas accounting and state revertions (REVERT) may not work. I haven't figured out a way to test this other than console-logging heavily (my eyes are scared of hex now!!).
- learnevm.com
- Yellow Paper
- Evmfromscratch
- Building an EVM from Scratch by 0xkarmacoma
- A Playdate with the EVM