🎯 Democratic DAOs Shouldn't Require Crypto to Vote
The paradox: A DAO claims to be decentralized and democratic, but only members who hold ETH for gas fees can actually participate in governance. What good is decentralization if 80% of token holders can't vote because they don't know how to buy Ethereum?

Technical subtitle: EIP-712 meta-transactions with ERC-2771 and Relayer pattern for gasless governance
📊 The Participation Problem That Every DAO Faces
In traditional DAOs, governance participation suffers from a fundamental barrier: gas fees.
| Barrier | Impact |
|---|---|
| Need to buy ETH | Non-crypto users can't participate at all |
| Gas volatility | During busy periods, voting can cost $50-$200 |
| Wallet complexity | Connecting MetaMask and approving transactions confuses users |
| Transaction fatigue | Every vote requires a separate on-chain transaction |
The result? Most DAOs have 2-5% participation rates. The vast majority of token holders are silent because the friction is too high.
flowchart TD
A[DAO Token Holder] --> B{Has ETH for gas?}
B -- No --> C[Cannot Vote]
B -- Yes --> D{Wants to buy ETH?}
D -- No --> C
D -- Yes --> E[Can Vote - But High Friction]
style C fill:#ffcccc,stroke:#ff0000
style E fill:#fff3e0,stroke:#ffa000This isn't just a UX problem — it's a fundamental flaw in DAO design. True governance requires participation, and participation requires accessibility.
💡 The Solution: Web2 UX with Web3 Security
The key insight: separate who signs the vote from who pays the blockchain fee.
sequenceDiagram
participant U as 👤 User (No ETH needed)
participant W as 💼 Wallet
participant R as ⚡ Relayer API
participant C as 📋 DAO Contract
U->>W: Sign vote EIP-712 (free, no gas)
W-->>U: Returns Signature
U->>R: POST /api/relay {signature}
R->>C: executeMetaTx(signature)
C-->>R: Vote registered on-chain
R-->>U: 200 OK {txHash}
note over U,C: The user never pays gas. The Relayer does.How It Works — In Plain Language
- User signs their vote — just like clicking "Like" on social media, no crypto needed
- A server relays the vote — pays the gas fee on behalf of the user
- Vote is recorded on-chain — immutable and verifiable by anyone
The user gets Web2 simplicity (click and vote). The blockchain gets Web3 security (immutable, verifiable records).
Implementation: The Technical Architecture
The Meta-Transaction Stack
| Technology | Purpose | Why It Matters |
|---|---|---|
| EIP-712 | Typed structured data signatures | Users see what they're signing in readable format |
| ERC-2771 | Standard for meta-transaction contracts | Extracts the real msg.sender from calldata |
| Relayer | Next.js API route that pays gas | Bridges user intent to on-chain execution |
Smart Contracts (Solidity ^0.8.24)
The system has three main contracts working together:
graph TB
subgraph Smart Contracts
GT[GovernanceToken<br/>ERC-20 + Delegation]
GD[GovernorDAO<br/>Proposals & Votes]
FW[Forwarder<br/>ERC-2771]
end
subgraph Frontend
N[Next.js 15<br/>Wagmi + Viem]
end
subgraph Backend
R[Relayer API<br/>Meta-transactions]
end
N -->|Read| GT
N -->|Read| GD
N -->|EIP-712 Sign| R
R -->|executeMetaTx| FW
FW -->|Verifies| GD
GD -->|Checks balance| GT
style GT fill:#1a1a2e,stroke:#00f2ff,stroke-width:2px,color:#fff
style GD fill:#1a1a2e,stroke:#00ff88,stroke-width:2px,color:#fff
style FW fill:#1a1a2e,stroke:#ff00f2,stroke-width:2px,color:#fffGovernanceToken.sol— ERC-20 with vote delegation. Holders can delegate voting power to others.GovernorDAO.sol— Proposal creation, voting lifecycle, and execution.Forwarder.sol— ERC-2771 implementation that verifies and forwards meta-transactions.
Proposal Lifecycle
stateDiagram-v2
[*] --> Pending: Creation (≥10% tokens)
Pending --> Active: Voting starts
Active --> Succeeded: Majority for
Active --> Defeated: Majority against
Succeeded --> Executed: On-chain execution
Defeated --> [*]
Executed --> [*]Proposal requirements: Only accounts with ≥ 10% of total tokens can create proposals. This prevents governance spam.
Frontend (Next.js 15 + TypeScript)
The frontend in packages/web/src/ uses:
- Wagmi + Viem: Type-safe EVM interaction hooks
- TanStack Query: Blockchain state cache with auto-revalidation
- Tailwind CSS + Headless UI: Accessible, responsive interface
- Real-time dashboard: Live proposal status and vote counts
🧠 Deep Dive: The ERC-2771 Magic
Extracting the Real Sender
The most complex part: the contract must know who actually voted, not who paid the gas.
This pattern in Forwarder.sol is the critical piece — it allows the contract to distinguish between a direct call and a forwarded meta-transaction.
Why EIP-712 Matters for UX
When users sign with EIP-712, MetaMask shows readable structured data instead of hex strings:
This prevents phishing and ensures users understand what they're signing.
📈 Impact: What Gasless Voting Enables
| Metric | Traditional DAO | Gasless DAO |
|---|---|---|
| Participation rate | 2-5% | Potentially 30-50% |
| Barrier to entry | Must buy ETH, learn wallets | Just connect wallet |
| Cost per vote | $0.50 - $50+ | $0 (user pays nothing) |
| Non-crypto users | Cannot participate | Can participate |
🤔 Why This Matters Beyond DAOs
The meta-transaction pattern applies to any decentralized system that needs user participation:
- DeFi voting on protocol upgrades — make it accessible to token holders who aren't traders
- NFT community governance — let holders vote without requiring ETH
- Decentralized social platforms — enable content moderation votes without gas barriers
- Token-gated applications — access control without transaction friction
✅ Lessons Learned
- Meta-transactions are powerful but complex — correctly implementing ERC-2771 verification was the biggest technical challenge
- EIP-712 transforms UX — showing structured data instead of hex dramatically improves user confidence
- The Relayer is a trust assumption — the relayer could censor votes; future iterations should support multiple relayers
🔗 Explore the Code
Full source code: github.com/87maxi/dao
Key files:
contracts/GovernanceToken.sol— ERC-20 with vote delegationcontracts/GovernorDAO.sol— Proposal logic and lifecyclecontracts/Forwarder.sol— ERC-2771 meta-transaction implementationpackages/web/src/— Next.js frontendpackages/web/src/app/api/relay/route.ts— Relayer API endpoint
Try it: Clone the repo, run
anvillocally, and deploy the contracts. Connect your wallet, delegate tokens, and cast a gasless vote — you'll sign with EIP-712 and the local relayer handles the rest.
Project from the Blockchain and Web3 Master — CodeCrypto Academy
💡 The Solution: Separating Signature from Payment
The concept is based on the separation between who signs and who pays the gas:
sequenceDiagram
participant U as 👤 User
participant W as 💼 Wallet
participant R as ⚡ Relayer API
participant C as 📋 DAO Contract
U->>W: Sign vote EIP-712 (free)
W-->>U: Returns Signature
U->>R: POST /api/relay {signature}
R->>C: executeMetaTx(signature)
C-->>R: Vote registered on-chain
R-->>U: 200 OK {txHash}
note over U,C: The user never pays gasThe Meta-Transaction Stack
- EIP-712: For signing structured data (the vote) in a typed and secure way. The wallet shows the user exactly what they're signing in readable language.
- ERC-2771: Standard for contracts that accept meta-transactions. Extracts the real
msg.senderfrom calldata, allowing the contract to know who actually voted (not the Relayer). - Relayer Service: A Next.js API route acting as intermediary, verifies the signature, pays the gas, and forwards the signed transaction.
🏗️ System Architecture
Smart Contracts (Solidity ^0.8.24)
The system has three main contracts working together:
graph TB
subgraph Smart Contracts
GT[GovernanceToken<br/>ERC-20 + Delegation]
GD[GovernorDAO<br/>Proposals & Votes]
FW[Forwarder<br/>ERC-2771]
end
subgraph Frontend
N[Next.js 15<br/>Wagmi + Viem]
end
subgraph Backend
R[Relayer API<br/>Meta-transactions]
end
N -->|Read| GT
N -->|Read| GD
N -->|EIP-712 Sign| R
R -->|executeMetaTx| FW
FW -->|Verifies| GD
GD -->|Checks balance| GT
style GT fill:#1a1a2e,stroke:#00f2ff,stroke-width:2px,color:#fff
style GD fill:#1a1a2e,stroke:#00ff88,stroke-width:2px,color:#fff
style FW fill:#1a1a2e,stroke:#ff00f2,stroke-width:2px,color:#fff-
GovernanceToken.sol: ERC-20 with vote delegation capability. Holders can delegate their voting power to other addresses. -
GovernorDAO.sol: Proposal logic and lifecycle. Manages proposal creation, voting, and execution. -
Forwarder.sol: ERC-2771 implementation that verifies and forwards meta-transactions.
Proposal Lifecycle
stateDiagram-v2
[*] --> Pending: Creation (≥10% tokens)
Pending --> Active: Voting starts
Active --> Succeeded: Majority for
Active --> Defeated: Majority against
Succeeded --> Executed: On-chain execution
Defeated --> [*]
Executed --> [*]Proposal Requirements
Only accounts with ≥ 10% of total tokens can create proposals. This prevents governance spam and ensures only proposals with significant backing reach voting.
Frontend (Next.js 15 + TypeScript)
The frontend, located in packages/web/src/, uses:
- Wagmi + Viem: Low-level hooks for type-safe EVM interaction
- TanStack Query: Blockchain state cache with automatic revalidation
- Tailwind CSS + Headless UI: Accessible and responsive UI
- Real-time dashboard: Live proposal status and vote count
🧠 Lessons Learned
Meta-transactions are complex but powerful
The biggest challenge was correctly implementing the verification flow in ERC-2771. The contract needs to know who the true sender is, not the Relayer paying the gas.
This pattern, implemented in Forwarder.sol, is the key piece that allows the system to work: the contract can distinguish between a direct call and a forwarded meta-transaction.
Governance UX is Hard
Decentralized governance demands that the user understands well what they're signing. The EIP-712 model helps because the wallet (MetaMask, Rabby) shows the readable structure of the message before signing:
🔗 Source Code
Repository: github.com/87maxi/dao
Key files:
contracts/GovernanceToken.sol- ERC-20 token with vote delegationcontracts/GovernorDAO.sol- Proposal logic and lifecyclecontracts/Forwarder.sol- ERC-2771 implementation for meta-transactionspackages/web/src/- Next.js frontend with real-time dashboardpackages/web/src/app/api/relay/route.ts- Relayer endpoint
Project from the Blockchain and Web3 Master — CodeCrypto Academy