An open API service indexing awesome lists of open source software.

https://github.com/StrobeLabs/eth.zig

Zig Ethereum client library. Faster than alloy.rs on 20/26 benchmarks.
https://github.com/StrobeLabs/eth.zig

abi blockchain crypto defi ens erc20 erc721 ethereum ethereum-library ethereum-sdk evm hd-wallet json-rpc keccak rlp secp256k1 web3 zig zig-ethereum zig-package

Last synced: 1 day ago
JSON representation

Zig Ethereum client library. Faster than alloy.rs on 20/26 benchmarks.

Awesome Lists containing this project

README

          

# eth.zig

[![CI](https://github.com/strobelabs/eth.zig/actions/workflows/ci.yml/badge.svg)](https://github.com/strobelabs/eth.zig/actions/workflows/ci.yml)
[![Docs](https://img.shields.io/badge/docs-ethzig.org-blue)](https://ethzig.org)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
[![Zig](https://img.shields.io/badge/Zig-%E2%89%A5%200.15.2-orange)](https://ziglang.org/)

**The fastest Ethereum library.** Beats Rust's alloy.rs on 23 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.

**[Read the docs at ethzig.org](https://ethzig.org)**

## Why eth.zig?

**Fastest Ethereum library** -- eth.zig [beats alloy.rs](bench/RESULTS.md) (Rust's leading Ethereum library, backed by Paradigm) on **23 out of 26 benchmarks**. ECDSA signing 2.09x faster, ABI decoding up to 7.65x, secp256k1 recovery 3.23x, mulDiv 1.76x, u256 division 5.57x, Keccak hashing up to 1.26x. See the [full results](bench/RESULTS.md).

**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.

## Performance vs alloy.rs

eth.zig wins **23/26 benchmarks** against [alloy.rs](https://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 |
|-----------|---------|----------|--------|
| secp256k1 sign | 24,481 ns | 51,286 ns | **zig 2.09x** |
| secp256k1 sign+recover | 67,816 ns | 218,720 ns | **zig 3.23x** |
| Keccak-256 (32B) | 268 ns | 337 ns | **zig 1.26x** |
| Keccak-256 (4KB) | 7,886 ns | 9,238 ns | **zig 1.17x** |
| ABI encode (static) | 24 ns | 100 ns | **zig 4.17x** |
| ABI encode (dynamic) | 176 ns | 325 ns | **zig 1.85x** |
| ABI decode (uint256) | 16 ns | 51 ns | **zig 3.19x** |
| ABI decode (dynamic) | 34 ns | 260 ns | **zig 7.65x** |
| u256 mulDiv (512-bit) | 17 ns | 30 ns | **zig 1.76x** |
| u256 division | 7 ns | 39 ns | **zig 5.57x** |
| u256 multiply | 4 ns | 9 ns | **zig 2.25x** |
| UniswapV2 getAmountOut | 21 ns | 27 ns | **zig 1.29x** |
| UniswapV4 swap | 42 ns | 47 ns | **zig 1.12x** |
| TX hash (EIP-1559) | 333 ns | 407 ns | **zig 1.22x** |

alloy.rs wins on address hex parsing (1.36x -- SIMD) and RLP u256 decoding (1.40x). See [full results](bench/RESULTS.md).

## Quick Start

### Derive an address from a private key

```zig
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"
```

### Sign and send a transaction

```zig
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),
});
```

### Read an ERC-20 token

```zig
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);
```

### Function selectors and event topics

```zig
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)")
```

### HD wallet from mnemonic

```zig
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();
```

## Built with eth.zig

Real production bots and SDKs built on eth.zig:

| Project | Description | Language |
|---------|-------------|----------|
| [perpcity-zig-sdk](https://github.com/StrobeLabs/perpcity-zig-sdk) | High-performance SDK for the PerpCity perpetual futures protocol on Base. Comptime ABI encoding, lock-free nonce management, 2-tier price cache. | Zig |
| [gator-liquidators](https://github.com/StrobeLabs/gator-liquidators) | Production liquidation keeper for PerpCity. Batch-checks positions via Multicall3, pre-signs liquidation txs, submits to Base sequencer. | Zig |

```text
eth.zig
└── perpcity-zig-sdk (protocol SDK with comptime contract ABIs)
└── gator-liquidators (production liquidation bot on Base)
```

Built something with eth.zig? Open a PR to add it here.

## Installation

**One-liner:**

```bash
zig fetch --save git+https://github.com/StrobeLabs/eth.zig.git#v0.2.2
```

**Or add manually** to your `build.zig.zon`:

```zig
.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`:

```zig
const eth_dep = b.dependency("eth", .{
.target = target,
.optimize = optimize,
});
exe.root_module.addImport("eth", eth_dep.module("eth"));
```

## Examples

The [`examples/`](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:

```bash
cd examples && zig build && ./zig-out/bin/01_derive_address
```

## Modules

| 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`, `sse_transport`, `json_rpc`, `provider`, `subscription` | HTTP, WebSocket, and SSE 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 |

## Features

| 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 |

## Comparison with Other Libraries

### Performance vs alloy.rs (Rust)

| Category | eth.zig | alloy.rs |
|----------|---------|----------|
| Benchmarks won | **23/26** | 2/26 |
| secp256k1 signing | Faster (2.09-3.23x) | -- |
| ABI encoding/decoding | Faster (1.85-7.65x) | -- |
| Hashing (Keccak) | Faster (1.17-1.26x) | -- |
| u256 arithmetic | Faster on all ops (1.12-5.57x) | -- |
| Hex operations | Faster (1.05-1.22x) | Faster on hex parsing (1.36x, SIMD) |

### Features vs Zabi (Zig)

| Feature | eth.zig | Zabi |
|---------|---------|------|
| Comptime selectors | Yes | No |
| secp256k1 ECDSA | Yes (libsecp256k1 + Zig fallback) | Yes (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 |

## Requirements

- Zig >= 0.15.2

## Running Tests

```bash
zig build test # Unit tests
zig build integration-test # Integration tests (requires Anvil)
```

## Benchmarks

One command to run the full comparison (requires Zig, Rust, Python 3):

```bash
bash bench/compare.sh
```

Or run individually:

```bash
zig build bench # eth.zig only
```

## Contributing

Contributions are welcome. Please open an issue or pull request on [GitHub](https://github.com/StrobeLabs/eth.zig).

Before submitting:

1. Run `zig build test` and ensure all tests pass.
2. Follow the existing code style -- comptime where possible.
3. Add tests for any new functionality.

## License

MIT -- see [LICENSE](LICENSE) for details.

Copyright 2025-2026 Strobe Labs