The fastest Ethereum library. Beats Rust's alloy.rs on 20 out of 26 benchmarks.
A complete Ethereum client library written in Zig -- ABI encoding, RLP serialization, secp256k1 signing, Keccak-256 hashing, HD wallets, ERC-20/721 tokens, JSON-RPC, ENS, and more. Just zig build.
Fastest Ethereum library -- eth.zig beats alloy.rs (Rust's leading Ethereum library, backed by Paradigm) on 20 out of 26 benchmarks. ABI decoding up to 7.94x faster, Keccak hashing up to 1.34x, u256 division 4x, UniswapV2 getAmountOut 1.30x, transaction hashing 1.27x. See the full results.
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.
Complete -- ABI, RLP, secp256k1, Keccak-256, BIP-32/39/44 HD wallets, EIP-712, JSON-RPC, WebSocket, ENS, ERC-20/721 -- everything you need for Ethereum in one package.
eth.zig wins 20/26 benchmarks against alloy.rs. Measured on Apple Silicon, ReleaseFast (Zig) vs --release (Rust). Criterion-style harness with 0.5s warmup and 2s measurement.
| Operation | eth.zig | alloy.rs | Winner |
|---|---|---|---|
| Keccak-256 (32B) | 135 ns | 179 ns | zig 1.33x |
| Keccak-256 (4KB) | 4,097 ns | 4,826 ns | zig 1.18x |
| ABI encode (static) | 13 ns | 51 ns | zig 3.92x |
| ABI encode (dynamic) | 91 ns | 171 ns | zig 1.88x |
| ABI decode (uint256) | 8 ns | 26 ns | zig 3.25x |
| ABI decode (dynamic) | 17 ns | 135 ns | zig 7.94x |
| Address derivation | 136 ns | 190 ns | zig 1.40x |
| Checksum address | 161 ns | 201 ns | zig 1.25x |
| u256 multiply | 2 ns | 5 ns | zig 2.50x |
| u256 division | 3 ns | 12 ns | zig 4.00x |
| UniswapV2 getAmountOut | 10 ns | 13 ns | zig 1.30x |
| UniswapV4 swap | 22 ns | 24 ns | zig 1.09x |
| Hex encode (32B) | 11 ns | 12 ns | zig 1.09x |
| Hex decode (32B) | 12 ns | 14 ns | zig 1.17x |
| TX hash (EIP-1559) | 170 ns | 216 ns | zig 1.27x |
alloy.rs wins on secp256k1 signing (3.09x -- large precomputed EC tables), address hex parsing (1.33x -- SIMD), and u256 mulDiv (1.20x). See full results.
const eth = @import("eth");
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);
// "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"const eth = @import("eth");
var transport = eth.http_transport.HttpTransport.init(allocator, "https://rpc.example.com");
defer transport.deinit();
var provider = eth.provider.Provider.init(allocator, &transport);
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),
});const eth = @import("eth");
// Comptime selectors -- zero runtime cost
const balance_sel = eth.erc20.selectors.balanceOf;
// Or use the typed wrapper
var token = eth.erc20.ERC20.init(allocator, token_addr, &provider);
const balance = try token.balanceOf(holder_addr);
const name = try token.name();
defer allocator.free(name);const eth = @import("eth");
// Computed at compile time -- zero runtime cost
const transfer_sel = comptime eth.keccak.selector("transfer(address,uint256)");
// transfer_sel == [4]u8{ 0xa9, 0x05, 0x9c, 0xbb }
// Same function works at runtime too
const runtime_sel = eth.keccak.selector(runtime_signature);
const transfer_topic = comptime eth.keccak.hash("Transfer(address,address,uint256)");
// transfer_topic == keccak256("Transfer(address,address,uint256)")const eth = @import("eth");
const words = [_][]const u8{
"abandon", "abandon", "abandon", "abandon",
"abandon", "abandon", "abandon", "abandon",
"abandon", "abandon", "abandon", "about",
};
const seed = try eth.mnemonic.toSeed(&words, "");
const key = try eth.hd_wallet.deriveEthAccount(seed, 0);
const addr = key.toAddress();One-liner:
zig fetch --save git+https://github.com/StrobeLabs/eth.zig.git#v0.2.2Or add manually to your build.zig.zon:
.dependencies = .{
.eth = .{
.url = "git+https://github.com/StrobeLabs/eth.zig.git#v0.2.2",
.hash = "...", // run `zig build` and it will tell you the expected hash
},
},Then import in your build.zig:
const eth_dep = b.dependency("eth", .{
.target = target,
.optimize = optimize,
});
exe.root_module.addImport("eth", eth_dep.module("eth"));The examples/ directory contains self-contained programs demonstrating each major feature:
| Example | Description | Requires RPC |
|---|---|---|
01_derive_address |
Derive address from private key | No |
02_check_balance |
Query ETH balance via JSON-RPC | Yes |
03_sign_message |
EIP-191 personal message signing | No |
04_send_transaction |
Send ETH with Wallet | Yes (Anvil) |
05_read_erc20 |
ERC-20 module API showcase | Yes |
06_hd_wallet |
BIP-44 HD wallet derivation | No |
07_comptime_selectors |
Comptime function selectors | No |
Run any example:
cd examples && zig build && ./zig-out/bin/01_derive_address| Layer | Modules | Description |
|---|---|---|
| Primitives | primitives, uint256, hex |
Address, Hash, Bytes32, u256, hex encoding |
| Encoding | rlp, abi_encode, abi_decode, abi_types |
RLP and ABI encoding/decoding |
| Crypto | secp256k1, signer, signature, keccak, eip155 |
ECDSA signing (RFC 6979), Keccak-256, EIP-155 |
| Types | transaction, receipt, block, blob, access_list |
Legacy, EIP-2930, EIP-1559, EIP-4844 transactions |
| Accounts | mnemonic, hd_wallet |
BIP-32/39/44 HD wallets and mnemonic generation |
| Transport | http_transport, ws_transport, json_rpc, provider, subscription |
HTTP and WebSocket JSON-RPC transports |
| ENS | ens_namehash, ens_resolver, ens_reverse |
ENS name resolution and reverse lookup |
| Client | wallet, contract, multicall, event, erc20, erc721 |
Signing wallet, contract interaction, Multicall3, token wrappers |
| Standards | eip712, abi_json |
EIP-712 typed data signing, Solidity JSON ABI parsing |
| Chains | chains |
Ethereum, Arbitrum, Optimism, Base, Polygon definitions |
| Feature | Status |
|---|---|
| Primitives (Address, Hash, u256) | Complete |
| RLP encoding/decoding | Complete |
| ABI encoding/decoding (all Solidity types) | Complete |
| Keccak-256 hashing | Complete |
| secp256k1 ECDSA signing (RFC 6979, EIP-2 low-S) | Complete |
| Transaction types (Legacy, EIP-2930, EIP-1559, EIP-4844) | Complete |
| EIP-155 replay protection | Complete |
| EIP-191 personal message signing | Complete |
| EIP-712 typed structured data signing | Complete |
| EIP-55 address checksums | Complete |
| BIP-32/39/44 HD wallets | Complete |
| HTTP transport | Complete |
| WebSocket transport (with TLS) | Complete |
| JSON-RPC provider (24+ methods) | Complete |
| ENS resolution (forward + reverse) | Complete |
| Contract read/write helpers | Complete |
| Multicall3 batch calls | Complete |
| Event log decoding and filtering | Complete |
| Chain definitions (5 networks) | Complete |
| Unit conversions (Wei/Gwei/Ether) | Complete |
| ERC-20 typed wrapper | Complete |
| ERC-721 typed wrapper | Complete |
| JSON ABI parsing | Complete |
| EIP-7702 transactions | Planned |
| IPC transport | Planned |
| Provider middleware (retry, caching) | Planned |
| Hardware wallet signers | Planned |
| Category | eth.zig | alloy.rs |
|---|---|---|
| Benchmarks won | 20/26 | 4/26 |
| ABI encoding/decoding | Faster (2.23-7.94x) | -- |
| Hashing (Keccak) | Faster (1.18-1.34x) | -- |
| u256 arithmetic | Faster on add/mul/div/V2/V4 | Faster on mulDiv (1.20x) |
| Hex operations | Faster (1.09-1.17x) | -- |
| secp256k1 signing | -- | Faster (3.09x, larger precomputed tables) |
| Feature | eth.zig | Zabi |
|---|---|---|
| Comptime selectors | Yes | No |
| Pure Zig secp256k1 | Yes | No (C binding) |
| ABI encode/decode | Yes | Yes |
| HD wallets (BIP-32/39/44) | Yes | Yes |
| ERC-20/721 wrappers | Yes | No |
| JSON ABI parsing | Yes | Yes |
| WebSocket transport | Yes | Yes |
| ENS resolution | Yes | Yes |
| EIP-712 typed data | Yes | Yes |
| Multicall3 | Yes | No |
- Zig >= 0.15.2
zig build test # Unit tests
zig build integration-test # Integration tests (requires Anvil)One command to run the full comparison (requires Zig, Rust, Python 3):
bash bench/compare.shOr run individually:
zig build bench # eth.zig onlyContributions are welcome. Please open an issue or pull request on GitHub.
Before submitting:
- Run
zig build testand ensure all tests pass. - Follow the existing code style -- comptime where possible.
- Add tests for any new functionality.
MIT -- see LICENSE for details.
Copyright 2025-2026 Strobe Labs