| Crates.io | guillotine-rs |
| lib.rs | guillotine-rs |
| version | 0.1.3 |
| created_at | 2025-09-09 12:02:49.74115+00 |
| updated_at | 2025-10-24 23:54:10.14102+00 |
| description | High-performance REVM-compatible EVM execution backed by Zig's guillotine-mini engine with FFI integration |
| homepage | https://github.com/evmts/guillotine-rs |
| repository | https://github.com/evmts/guillotine-rs |
| max_upload_size | |
| id | 1830687 |
| size | 200,855 |
Zig is required to build the underlying EVM engine. Install it before building:
macOS:
brew install zig
Linux / Windows: Download from https://ziglang.org/download/
Verify installation:
zig version # Should show 0.15.1 or later
Recommended: Build from source with git submodules
git clone --recursive https://github.com/evmts/guillotine-rs.git
cd guillotine-rs
cargo build --release
Alternative: Add to your Cargo.toml
[dependencies]
guillotine-rs = { git = "https://github.com/evmts/guillotine-rs", submodules = true }
Note: Installing directly from crates.io (cargo add guillotine-rs) is not currently supported due to git submodule dependencies. You must clone the repository with --recursive to include the guillotine-mini submodule.
tests/ — Example code and usage
LLMS.txt — For LLMs
High-performance REVM execution backed by the Zig-based guillotine-mini engine. Thin Rust wrapper with FFI to Zig for execution, state sync, logs, refunds, and storage changes.
lib/guillotine-mini) — core EVM, opcode handlers, storage managerroot_c.zig in guillotine-mini) — stable C ABI to create/destroy EVM, set contexts, execute, and extract resultssrc/guillotine_mini) — REVM adapter, type conversions, and state bridgeContext and TxEnvEvmAdapterError<DbErr>Legend: All FFI calls are wrapped with safe Rust interfaces
GuillotineMiniEvm — main EVM wrapper for REVM integration
EvmAdapterError — typed error handling
Db(DbErr) — database-related error from REVMFfi(&'static str) — FFI call failed (bool=false or null handle)
sync_account_to_ffi — sync REVM account state to guillotine-mini (balance, nonce, code)sync_storage_to_ffi — sync single storage slot to guillotine-miniread_storage_from_ffi — read storage value from guillotine-mini
evm_create — create EVM instance with hardfork nameevm_destroy — free EVM resourcesevm_set_bytecode — set contract bytecode for executionevm_set_execution_context — set caller, address, value, gas, calldataevm_set_block_context — set block number, timestamp, gas limit, etc.evm_execute — execute transaction and return success/failureevm_get_status — check if execution succeededevm_get_gas_used — get gas consumed by executionevm_get_gas_refund — get gas refund counterevm_get_output_size — get return data lengthevm_copy_output — copy return data to bufferevm_set_storage — set storage slot valueevm_get_storage — get storage slot valueevm_set_balance — set account balanceevm_set_code — set account codeevm_set_nonce — set account nonceevm_get_log_count — get number of emitted logsevm_get_log — get log entry by index (address, topics, data)evm_get_storage_change_count — get number of storage changesevm_get_storage_change — get storage change by index (address, slot, value)
address_to_bytes — convert REVM Address to [20]u8address_from_bytes — convert [20]u8 to REVM Addressu256_to_be_bytes — convert U256 to big-endian [32]u8u256_from_be_bytes — convert big-endian [32]u8 to U256i64_to_u64_gas — convert signed gas to unsigned (clamp negative)ExecutionResult::Revert { gas_used, output } (no panic)ExecutionResult::Success { reason: Return, gas_used, gas_refunded, logs, output }EvmAdapterError::Ffi(&'static str)EvmAdapterError::Db(DbErr) and propagatedFallible constructor available: GuillotineMiniEvm::try_new(ctx) returns Result<Self, EvmAdapterError>. The new(ctx) constructor retains an assert on fatal creation failure for convenience.
use guillotine_rs::guillotine_mini::evm::GuillotineMiniEvm;
use revm::{
context::Context,
context_interface::result::ExecutionResult,
database_interface::EmptyDB,
primitives::{address, TxEnv, TxKind, U256},
};
// Create REVM context
let ctx = Context::mainnet().with_db(EmptyDB::default());
let mut evm = GuillotineMiniEvm::new(ctx);
// Build transaction
let tx = TxEnv::builder()
.caller(address!("a94f5374fce5edbc8e2a8697c15331677e6ebf0b"))
.kind(TxKind::Call(address!("0000000000000000000000000000000000000001")))
.gas_limit(100_000)
.build()
.unwrap();
// Execute and get results
let result = evm.transact(tx).unwrap();
match result.result {
ExecutionResult::Success { gas_used, gas_refunded, logs, output, .. } => {
println!("Success! Gas used: {}, refunded: {}", gas_used, gas_refunded);
println!("Logs: {}, Output: {:?}", logs.len(), output);
}
ExecutionResult::Revert { gas_used, output } => {
println!("Reverted! Gas used: {}, Output: {:?}", gas_used, output);
}
_ => unreachable!(),
}
# Run all tests
cargo test
# Run specific test
cargo test test_simple_add
# Run with output
cargo test -- --nocapture
Test coverage:
"Zig compiler not found!"
# Install Zig 0.15.1 or later
brew install zig # macOS
# or download from https://ziglang.org/download/
# Verify installation
zig version
"Zig version too old!"
# Upgrade to Zig 0.15.1+
brew upgrade zig # macOS
# or download latest from https://ziglang.org/download/
"git submodule init failed"
# If you installed via cargo, clone manually instead:
git clone --recursive https://github.com/evmts/guillotine-rs
cd guillotine-rs
cargo build
"Failed to initialize submodules"
# Initialize submodules manually:
git submodule update --init --recursive
cargo build
"zig build failed"
cd lib/guillotine-mini
rm -rf zig-out zig-cache
cd ../..
cargo clean
cargo build
Guillotine Mini — Minimal Zig EVM implementation
Primitives — Ethereum primitives and cryptography for Zig
REVM — Rust Ethereum Virtual Machine