eth.zig

eth.zig

The fastest Ethereum library. Beats Rust on 18 of 26 benchmarks.

The fastest Ethereum library. Beats alloy.rs on 18 of 26 benchmarks.

eth.zig provides everything you need to interact with Ethereum from Zig -- signing transactions, encoding ABI calls, managing HD wallets, reading ERC-20 tokens, talking to nodes over JSON-RPC, and more.

Why eth.zig?

  • Faster than Rust -- eth.zig beats alloy.rs (Rust's leading Ethereum library, backed by Paradigm) on 18 out of 26 benchmarks, including secp256k1 signing (2.34x), ABI decoding (8.41x), mulDiv (1.82x), u256 division (3.43x), and Keccak-256 hashing of small inputs.
  • Comptime-first -- Function selectors and event topics are computed at compile time with zero runtime cost. The compiler does the hashing so your program doesn't have to.

Performance vs alloy.rs

eth.zig wins 18/26 benchmarks against alloy.rs (alloy-primitives 1.6.0, alloy-consensus 2.0.5; run 2026-06-10). Measured on Apple Silicon, ReleaseFast (Zig) vs --release (Rust).

Operationeth.zigalloy.rsWinner
secp256k1 sign22,033 ns51,490 nszig 2.34x
secp256k1 sign+recover52,095 ns220,150 nszig 4.23x
ABI decode (dynamic)32 ns269 nszig 8.41x
ABI encode (static)25 ns97 nszig 3.88x
RLP encode (EIP-1559 tx)3 ns73 nszig 24.33x
u256 division7 ns24 nszig 3.43x
u256 mulDiv (512-bit)17 ns31 nszig 1.82x
Keccak-256 (32B)263 ns319 nszig 1.21x
TX hash (EIP-1559)271 ns361 nszig 1.33x

See the full benchmark results for all 26 operations.

Quick Start

const std = @import("std");
const eth = @import("eth");

pub fn main() !void {
    var gpa: std.heap.GeneralPurposeAllocator(.{}) = .init;
    defer _ = gpa.deinit();
    const allocator = gpa.allocator();

    // WARNING: This is the default Anvil/Hardhat test key. Never use it for real funds.
    const private_key = try eth.hex.hexToBytesFixed(32, "ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80");
    const signer = eth.signer.Signer.init(private_key);
    const addr = try signer.address();
    const checksum = eth.primitives.addressToChecksum(&addr);
    _ = checksum;

    // Sign and send a transaction
    var transport = eth.http_transport.HttpTransport.init(allocator, "https://rpc.example.com", eth.runtime.blockingIo());
    defer transport.deinit();
    var provider = eth.provider.Provider.init(allocator, &transport);

    const recipient_address = try eth.hex.hexToBytesFixed(20, "0000000000000000000000000000000000000000");
    var wallet = eth.wallet.Wallet.init(allocator, private_key, &provider);
    const tx_hash = try wallet.sendTransaction(.{
        .to = recipient_address,
        .value = eth.units.parseEther(1.0),
    });
    _ = tx_hash;
}

Guides

Resources

On this page