Skip to content

Latest commit

Β 

History

History
606 lines (467 loc) Β· 17.6 KB

README.md

File metadata and controls

606 lines (467 loc) Β· 17.6 KB

πŸ“š Zigeth Examples

This directory contains comprehensive examples demonstrating the most common Ethereum operations using the zigeth library.

πŸ“‹ Examples Overview

Example File Description Difficulty
1 01_wallet_creation.zig Wallet creation and management ⭐ Beginner
2 02_query_blockchain.zig Querying blockchain data ⭐ Beginner
3 03_send_transaction.zig Sending transactions ⭐⭐ Intermediate
4 04_smart_contracts.zig Smart contract interaction ⭐⭐ Intermediate
5 05_transaction_receipts.zig Transaction receipts and status ⭐⭐ Intermediate
6 06_event_monitoring.zig Event monitoring and subscriptions ⭐⭐⭐ Advanced
7 07_complete_workflow.zig Complete end-to-end workflow ⭐⭐⭐ Advanced
8 08_account_abstraction.zig ERC-4337 Account Abstraction (AA) ⭐⭐⭐ Advanced
9 09_etherspot_userop.zig Etherspot UserOperation with v0.7 ⭐⭐⭐ Advanced

πŸš€ Running Examples

Prerequisites

  1. Install Zig 0.15.0 or later

    # Download from https://ziglang.org/download/
  2. Clone the zigeth repository

    git clone https://github.com/ch4r10t33r/zigeth.git
    cd zigeth
  3. Build the library

    zig build

Running an Example

To run any example:

# Run directly
zig run examples/01_wallet_creation.zig --dep zigeth -Mzigeth=src/root.zig --dep secp256k1 -Msecp256k1=<path> -lc

# Or compile first
zig build-exe examples/01_wallet_creation.zig --dep zigeth -Mzigeth=src/root.zig -lc
./01_wallet_creation

Using build.zig (Recommended)

Add to your build.zig:

// Add example builds
const examples = [_][]const u8{
    "01_wallet_creation",
    "02_query_blockchain",
    "03_send_transaction",
    "04_smart_contracts",
    "05_transaction_receipts",
    "06_event_monitoring",
    "07_complete_workflow",
};

for (examples) |example_name| {
    const example = b.addExecutable(.{
        .name = example_name,
        .root_source_file = b.path(b.fmt("examples/{s}.zig", .{example_name})),
        .target = target,
        .optimize = optimize,
    });
    
    example.root_module.addImport("zigeth", zigeth_mod);
    example.linkLibC();
    
    const run_example = b.addRunArtifact(example);
    const run_step = b.step(
        b.fmt("example-{s}", .{example_name}),
        b.fmt("Run example: {s}", .{example_name})
    );
    run_step.dependOn(&run_example.step);
}

Then run:

zig build example-01_wallet_creation
zig build example-02_query_blockchain
# etc.

πŸ“– Example Descriptions

1. Wallet Creation (01_wallet_creation.zig)

Learn how to:

  • Generate new random wallets
  • Import wallets from private keys
  • Export private keys securely
  • Use mnemonic phrases (BIP-39)
  • Create HD wallets (BIP-32/BIP-44)
  • Encrypt wallets with keystores
  • Sign messages

Topics covered: Wallet, HDWallet, Mnemonic, Keystore, Private keys

Use cases: Wallet apps, key management, account generation

2. Query Blockchain (02_query_blockchain.zig)

Learn how to:

  • Connect to Ethereum networks
  • Query account balances
  • Get current block number
  • Retrieve block details
  • Check gas prices
  • Get transaction counts (nonces)
  • Detect contract addresses
  • Query multiple chains

Topics covered: Providers, RPC, Blocks, Balances, Multi-chain

Use cases: Block explorers, analytics, monitoring

3. Send Transaction (03_send_transaction.zig)

Learn how to:

  • Create transactions (Legacy, EIP-1559)
  • Sign transactions with EIP-155
  • Use middleware for automation
  • Estimate gas limits
  • Set optimal gas prices
  • Manage nonces
  • Send transactions to network

Topics covered: Transactions, Middleware, Signing, Gas, Nonces

Use cases: Wallets, DeFi apps, transaction builders

4. Smart Contracts (04_smart_contracts.zig)

Learn how to:

  • Interact with ERC-20 tokens
  • Encode function calls
  • Use ABI encoding/decoding
  • Parse event signatures
  • Deploy contracts
  • Use pre-defined selectors

Topics covered: ABI, Contracts, Events, ERC standards

Use cases: DeFi, NFTs, Token interactions

5. Transaction Receipts (05_transaction_receipts.zig)

Learn how to:

  • Get transaction receipts
  • Check transaction status
  • Calculate transaction fees
  • Wait for confirmations
  • Parse event logs
  • Handle contract creation
  • Understand bloom filters

Topics covered: Receipts, Logs, Status, Fees

Use cases: Transaction tracking, confirmation monitoring

6. Event Monitoring (06_event_monitoring.zig)

Learn how to:

  • Use WebSocket subscriptions
  • Subscribe to new blocks
  • Monitor pending transactions
  • Filter contract events
  • Parse ERC-20 Transfer events
  • Query historical logs
  • Unsubscribe from events

Topics covered: WebSocket, Subscriptions, Events, Filters

Use cases: Real-time monitoring, event indexing, notifications

7. Complete Workflow (07_complete_workflow.zig)

Learn how to:

  • Execute a complete transaction flow
  • Use all components together
  • Follow best practices
  • Handle the full lifecycle

Topics covered: Everything (end-to-end)

Use cases: Complete applications, learning the full API

8. Account Abstraction (08_account_abstraction.zig)

Learn how to:

  • Work with ERC-4337 Account Abstraction
  • Use all three EntryPoint versions (v0.6, v0.7, v0.8)
  • Create UserOperations for different versions
  • Validate and size UserOperations
  • Use gas estimators and paymaster modes
  • Initialize account factories
  • Understand gas overhead constants

Topics covered:

  • EntryPoint versions (v0.6, v0.7, v0.8) and addresses
  • UserOperation creation and validation
  • Multi-version support via compile-time polymorphism
  • Gas estimation (local mode)
  • Paymaster modes (SPONSOR and ERC20)
  • Account factory initialization
  • Size comparison (v0.6 vs v0.7 - gas optimization)

Use cases:

  • Quick validation of AA library functionality
  • Learning EntryPoint versions and differences
  • Understanding UserOperation structure
  • Testing gas estimation
  • Exploring paymaster integration
  • Smart contract wallet development
  • DeFi applications with Account Abstraction

Key Features Demonstrated:

  • βœ… All 3 EntryPoint versions
  • βœ… Multi-version UserOperation support
  • βœ… Compile-time type validation
  • βœ… Gas overhead constants
  • βœ… Paymaster modes
  • βœ… Account factory pattern
  • βœ… Size optimization (v0.7: 148 bytes vs v0.6: 212 bytes)

9. Etherspot UserOperation (09_etherspot_userop.zig)

Learn how to:

  • Use Etherspot's Modular Smart Account Factory
  • Create a UserOperation for EntryPoint v0.7
  • Integrate with Etherspot Arka Paymaster
  • Submit to Etherspot Skandha Bundler
  • Build complete sponsored transaction workflow
  • Calculate CREATE2 addresses
  • Encode transactions and sign UserOperations
  • Poll for transaction receipts

Topics covered:

  • Etherspot infrastructure (Factory, Arka, Skandha)
  • EntryPoint v0.7 integration
  • Modular Smart Account deployment
  • Paymaster sponsorship (gasless transactions)
  • UserOperation creation and signing
  • JSON-RPC communication
  • Complete end-to-end workflow

Use cases:

  • Building dApps with Etherspot infrastructure
  • Sponsored transactions (no gas fees for users)
  • Smart contract wallet integration
  • Production AA implementations
  • Multi-chain deployment (Etherspot supports many networks)
  • Enterprise-grade AA solutions

Key Features Demonstrated:

  • βœ… Etherspot Modular Smart Account Factory
  • βœ… EntryPoint v0.7 (gas-optimized)
  • βœ… Arka Paymaster integration (pm_sponsorUserOperation)
  • βœ… Skandha Bundler submission (eth_sendUserOperation)
  • βœ… CREATE2 deterministic addresses
  • βœ… Complete UserOp lifecycle
  • βœ… JSON serialization for RPC
  • βœ… Production-ready workflow

Configuration:

  • Network: Sepolia Testnet (Chain ID: 11155111)
  • EntryPoint v0.7: 0x0000000071727De22E5E9d8BAf0edAc6f37da032
  • Factory: 0x7f6d8F107fE8551160BD5351d5F1514320aB6E50 (Etherspot Modular)
  • Paymaster: 0x00000000000De1aaB9389285965F49D387000000 (Arka)
  • Bundler RPC: https://sepolia-bundler.etherspot.io/v2 (Skandha)
  • Paymaster RPC: https://arka.etherspot.io (Arka API)

🎯 Common Patterns

Pattern 1: Simple Address Creation

// Easy way: Use hex string literals!
const address = try zigeth.primitives.Address.fromHex(
    allocator,
    "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
);

// For smart contracts too:
const usdc = try zigeth.primitives.Address.fromHex(
    allocator,
    "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"
);

Pattern 2: Simple Balance Check

var provider = try zigeth.providers.Networks.mainnet(allocator);
defer provider.deinit();

const address = try zigeth.primitives.Address.fromHex(allocator, "0x...");
const balance = try provider.getBalance(address);
const eth = try zigeth.utils.units.weiToEther(balance);
std.debug.print("Balance: {d} ETH\n", .{eth});

Pattern 3: Send ETH Transfer

// Setup
var provider = try zigeth.providers.Networks.sepolia(allocator);
var signer = try zigeth.middleware.SignerMiddleware.init(allocator, private_key, config);

// Create transaction
var tx = zigeth.types.Transaction.newEip1559(allocator);
tx.from = from_address;
tx.to = try zigeth.primitives.Address.fromHex(allocator, "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb");
tx.value = 100_000_000_000_000_000; // 0.1 ETH
tx.nonce = try provider.getTransactionCount(from_address);
tx.gas_limit = 21000;

// Sign and send
const raw_tx = try signer.signAndSerialize(&tx);
const tx_hash = try provider.sendRawTransaction(raw_tx);

// Wait for confirmation
const receipt = try provider.waitForTransaction(tx_hash, 60000);

Pattern 4: Read ERC-20 Balance

const balance_of = zigeth.abi.Function{
    .name = "balanceOf",
    .inputs = &[_]zigeth.abi.Parameter{
        .{ .name = "account", .type = address_type, .indexed = false },
    },
    .outputs = &[_]zigeth.abi.Parameter{
        .{ .name = "balance", .type = uint256_type, .indexed = false },
    },
    .state_mutability = .view,
};

const call_data = try zigeth.abi.encodeFunctionCall(allocator, balance_of, &params);
// Use provider.eth.call() to execute

Pattern 5: Account Abstraction - Sponsored Transaction

const aa = zigeth.account_abstraction;

// 1. Setup
const entry_point = try aa.EntryPoint.v07(allocator, &rpc_client);
var smart_account = aa.SmartAccount.init(
    allocator,
    account_address,
    entry_point.address,
    .v0_7,
    owner_address,
    &rpc_client,
    &factory,
    0, // salt
);

// 2. Create transaction
const call_data = try smart_account.encodeExecute(
    recipient_address,
    value, // Amount in wei
    &[_]u8{}, // Additional data if needed
);
defer allocator.free(call_data);

// 3. Estimate gas
var gas_estimator = aa.GasEstimator.init(allocator, null, &rpc_client);
const test_op = aa.UserOpUtils.zero(aa.types.UserOperationV07);
const gas_estimates = try gas_estimator.estimateGas(test_op);

// 4. Create UserOperation
const user_op_any = try smart_account.createUserOperation(call_data, gas_estimates);
var user_op = user_op_any.v07;

// 5. Get paymaster sponsorship (FREE for user!)
var paymaster = aa.PaymasterClient.init(allocator, paymaster_url, api_key);
defer paymaster.deinit();
try paymaster.sponsorUserOperation(&user_op, entry_point.address, .sponsor);

// 6. Sign
const signature = try smart_account.signUserOperation(user_op, private_key);
defer allocator.free(signature);
user_op.signature = signature;

// 7. Send to bundler
var bundler = aa.BundlerClient.init(allocator, bundler_url, entry_point.address);
defer bundler.deinit();
const user_op_hash = try bundler.sendUserOperation(user_op);

// 8. Wait for execution
const receipt = try bundler.getUserOperationReceipt(user_op_hash);
std.debug.print("Success: {}\n", .{receipt.?.success});

Pattern 6: Account Abstraction - Batch Transactions

// Execute multiple calls atomically
const batch_calls = [_]aa.Call{
    .{
        .to = usdc_address,
        .value = 0,
        .data = try encodeApprove(spender, amount), // Approve USDC
    },
    .{
        .to = dex_address,
        .value = 0,
        .data = try encodeSwap(usdc_address, eth_address, amount), // Swap on DEX
    },
};

const call_data = try smart_account.encodeExecuteBatch(&batch_calls);
defer allocator.free(call_data);

// Create UserOperation and send (same as Pattern 5)
// If one call fails, entire batch reverts (atomic)

⚠️ Important Notes

Testnet Usage

All examples that send transactions should use testnet networks:

Private Keys

Never use real private keys in examples or test code!

  • Use test mnemonics like: "test test test test test test test test test test test junk"
  • Generate new wallets for testing
  • Use testnet networks only

API Keys

The examples use Etherspot's public API key. For production:

  1. Get your own API key from Etherspot
  2. Replace in the RPC URLs
  3. Consider rate limits and usage quotas

πŸ”§ Troubleshooting

Example won't compile

# Make sure you're in the zigeth directory
cd zigeth

# Clean build cache
rm -rf zig-cache zig-out .zig-cache

# Rebuild
zig build

Import errors

Make sure you're using the correct module imports:

const zigeth = @import("zigeth");

// Then access modules:
zigeth.primitives.Address
zigeth.providers.Networks
zigeth.signer.Wallet
// etc.

Network connection errors

  • Check your internet connection
  • Verify the RPC endpoint is accessible
  • Check for rate limiting
  • Try a different network/provider

πŸ“š Learning Path

Recommended order for learning:

  1. Start with 01_wallet_creation.zig - Understand key management
  2. Move to 02_query_blockchain.zig - Learn data queries
  3. Try 03_send_transaction.zig - Send your first transaction
  4. Explore 04_smart_contracts.zig - Interact with contracts
  5. Study 05_transaction_receipts.zig - Understand receipts
  6. Experiment with 06_event_monitoring.zig - Real-time events
  7. Master 07_complete_workflow.zig - Put it all together
  8. Advanced: 08_account_abstraction.zig - ERC-4337 and smart accounts
  9. Production: 09_etherspot_userop.zig - Real-world AA with Etherspot

Alternative path for Account Abstraction developers:

  1. 01_wallet_creation.zig - Understand EOA (Externally Owned Accounts)
  2. 02_query_blockchain.zig - Learn blockchain queries
  3. 08_account_abstraction.zig - Learn AA fundamentals
  4. 09_etherspot_userop.zig - Production AA with Etherspot infrastructure
  5. 04_smart_contracts.zig - Understand contract interactions (AA uses these!)
  6. 07_complete_workflow.zig - Traditional workflow comparison

Fast track for Etherspot developers:

  1. 08_account_abstraction.zig - Understand ERC-4337 basics
  2. 09_etherspot_userop.zig - Complete Etherspot integration
  3. Start building your sponsored dApp!

🌐 Multi-Chain Support

All examples can be adapted for different networks:

// Ethereum
var provider = try zigeth.providers.Networks.mainnet(allocator);

// Polygon
var provider = try zigeth.providers.Networks.polygon(allocator);

// Arbitrum  
var provider = try zigeth.providers.Networks.arbitrum(allocator);

// Optimism
var provider = try zigeth.providers.Networks.optimism(allocator);

// Base
var provider = try zigeth.providers.Networks.base(allocator);

// Sepolia (testnet)
var provider = try zigeth.providers.Networks.sepolia(allocator);

// Local development
var provider = try zigeth.providers.Networks.localhost(allocator);

// Custom RPC
var provider = try zigeth.providers.Networks.custom(allocator, "https://your-rpc-url");

🀝 Contributing Examples

Have a useful example? Contributions are welcome!

  1. Create a new example file: XX_your_example.zig
  2. Follow the existing format:
    • Clear comments explaining what it does
    • Step-by-step code with output
    • Error handling
    • Resource cleanup
  3. Update this README with your example
  4. Submit a pull request!

πŸ’‘ Tips

  • Start simple: Begin with wallet creation and queries
  • Use testnets: Always test on Sepolia first
  • Check balances: Ensure sufficient funds before sending
  • Handle errors: Use try and catch appropriately
  • Clean up: Always use defer for resource cleanup
  • Read receipts: Always verify transaction success
  • Monitor gas: Use middleware for optimal gas prices

πŸ”— Additional Resources

General Ethereum Development

Account Abstraction (ERC-4337)

πŸ“ž Support


Happy coding with zigeth! πŸš€