An alpha EVM implementation in Zig, using threaded code dispatch for opcode execution. Osaka-compliant.
- Zig 0.15.2
zig buildRun unit tests:
zig build testRun the full state test suite after fetching the fixture archive and extracting it:
zig build state-testsRun a single fixture file:
zig build state-tests -Dstate-test=/path/to/fixture.jsonThe entry point for executing a transaction is EVM.init followed by EVM.process. You need to provide a Message (transaction parameters), a Context (block parameters), and a State (account/storage world state).
See example/main.zig for a working end-to-end example (zig build example to run it).
The EVM reads account balances, storage slots, and contract code through a CommittedState interface. Consumers provide their own implementation to back these reads with a real database, in-memory map, or anything else.
A CommittedState must be a struct exposing the same methods as the default implementation (evm/empty_committed_state.zig). See example/committed_state.zig for a working example.
Add zevm to your build.zig.zon:
.zevm = .{
.url = "git+https://github.com/omerfirmak/zevm.git#<commit>",
.hash = "<hash>",
},Then in your build.zig, pass your custom CommittedState source file when declaring the dependency:
const zevm_dep = b.dependency("zevm", .{
.target = target,
.optimize = optimize,
.committed_state = b.path("src/my_committed_state.zig"),
});
exe.root_module.addImport("zevm", zevm_dep.module("zevm"));If you omit .committed_state, the built-in empty implementation is used (returns zeros for everything).