Skip to content

Guillotine Docs (Alpha)

Purely functional docs. No marketing. If anything is unclear or wrong, open an issue.

Quick Start

  • Prerequisites: Zig 0.15.1+, Git
  • Build: zig build
  • Verify: zig build && zig build test-opcodes
  • Full test suite: zig build test (slower)

Core Commands

  • zig build: Build project
  • zig build test-opcodes: Run opcode differential tests
  • zig build test: Run all tests
  • zig build --list-steps: Show available steps

Minimal Example

This example executes a STOP-only contract at a fixed address.

const std = @import("std");
const primitives = @import("primitives");
const DefaultEvm = @import("evm").DefaultEvm;
const Database = @import("storage/database.zig").Database;
const BlockInfo = @import("block/block_info.zig").DefaultBlockInfo;
const TransactionContext = @import("block/transaction_context.zig").TransactionContext;
 
pub fn main() !void {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer _ = gpa.deinit();
    const allocator = gpa.allocator();
 
    var db = Database.init(allocator);
    defer db.deinit();
 
    const block = BlockInfo{
        .number = 1,
        .timestamp = 1,
        .difficulty = 0,
        .gas_limit = 30_000_000,
        .coinbase = primitives.ZERO_ADDRESS,
        .base_fee = 0,
        .prev_randao = [_]u8{0} ** 32,
    };
 
    const tx = TransactionContext{
        .gas_limit = 1_000_000,
        .coinbase = primitives.ZERO_ADDRESS,
        .chain_id = 1,
    };
 
    var evm = try DefaultEvm.init(allocator, &db, block, tx, 0, primitives.ZERO_ADDRESS, .CANCUN);
    defer evm.deinit();
 
    const addr: primitives.Address = .{ .bytes = [_]u8{0x12} ++ [_]u8{0} ** 19 };
    const bytecode = [_]u8{0x00}; // STOP
    const code_hash = try db.set_code(&bytecode);
    try db.set_account(addr.bytes, .{ .balance = 0, .nonce = 0, .code_hash = code_hash, .storage_root = [_]u8{0} ** 32 });
 
    const params = DefaultEvm.CallParams{ .call = .{
        .caller = primitives.ZERO_ADDRESS,
        .to = addr,
        .value = 0,
        .input = &.{},
        .gas = 100_000,
    } };
 
    const result = evm.call(params);
    if (!result.success) return error.ExecutionFailed;
}

Notes

  • Alpha quality; interfaces can change.
  • Tests print nothing on success by design.
  • For debug logs in tests:
test {
    std.testing.log_level = .debug;
}

Report issues and gaps on GitHub.