A decentralized to-do list application built on Ethereum blockchain, combining Solidity smart contracts with a modern React frontend. This project demonstrates blockchain integration for persistent, immutable task management.
- Decentralized Storage: All tasks are stored on the Ethereum blockchain
- MetaMask Integration: Connect your wallet to interact with the dApp
- Full CRUD Operations: Create, read, update, and delete tasks on-chain
- Real-time Updates: Automatic UI refresh after blockchain transactions via event listeners
- Network Switching: Seamlessly switch between Hardhat local and Sepolia testnet
- Due Dates: Set optional due dates with visual status indicators (overdue, today, tomorrow, upcoming)
- Event Emissions: Smart contract events for all operations
- Comprehensive Testing: 40+ unit tests ensuring contract reliability with 100% function coverage
- Solidity: ^0.8.0 with ownership logic and access control
- Hardhat: 2.22.6 for development and testing
- Ethers.js: ^6.16.0 for blockchain interaction
- Testing: Hardhat + Chai with 40+ test cases
- Gas Optimization: Swap-and-pop deletion pattern
- React: 18.x with modern hooks architecture
- Ethers.js: ^6.16.0 for Web3 integration
- MetaMask: Wallet provider with event listeners
- CSS: Custom styling with CSS variables for theming
- localStorage: Theme and preference persistence
- Custom Hooks: useWeb3, useContract, useTransactionHistory, useDarkMode
- Components: Modular, reusable UI components
- Utils: Formatter functions for addresses, dates, times
- State Management: React hooks with proper cleanup
- Event-Driven: Real-time UI updates via smart contract events
Contract Address: 0x5c25BA0202e8581f551e23d5aD13E745E557C644
Network: Sepolia (Chain ID: 11155111)
Explorer: https://sepolia.etherscan.io/address/0x5c25BA0202e8581f551e23d5aD13E745E557C644
Contract Address: 0x5FbDB2315678afecb367f032d93F642f64180aa3
Network: Hardhat Local (Chain ID: 31337)
createTask(string _title, string _description, uint _dueDate): Create a new task with optional due datetoggleTaskCompletion(uint _id): Toggle task completion status (owner only)deleteTask(uint _id): Delete a task by ID (owner only)getTask(uint _id): Retrieve a single task with all detailsgetAllTasks(): Retrieve all tasks from all usersgetUserTasks(address _user): Get all tasks owned by a specific addressgetMyTasks(): Get all tasks owned by the caller (msg.sender)
TaskCreated(uint id, string title, string description, uint dueDate, address owner)TaskCompleted(uint id, bool completed)TaskDeleted(uint id)
- Input Validation: Title required, max 200 chars; description max 1000 chars
- Ownership Control: Only task owners can modify or delete their tasks
- Access Restrictions: Clear revert messages for unauthorized actions
- Gas Optimization: Swap-and-pop deletion pattern to minimize gas costs
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β App.js (80 lines) β
β ββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Custom Hooks (Business Logic) β β
β β β’ useWeb3() - Wallet & Provider Management β β
β β β’ useContract() - Smart Contract Interactions β β
β β β’ useTransactionHistory() - Activity Tracking β β
β β β’ useDarkMode() - Theme Management β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββ β
β ββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β UI Components (Presentational) β β
β β β’ Header - Title, wallet, dark mode toggle β β
β β β’ TodoForm - Create new tasks β β
β β β’ TodoList - Display & filter tasks β β
β β β’ TodoItem - Individual task with actions β β
β β β’ TransactionHistory - Activity log β β
β β β’ NetworkWarning - Error/warning messages β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββ β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
β Ethers.js
βΌ
ββββββββββββββββββββββββββββββββββββ
β MetaMask Wallet β
ββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Ethereum Blockchain (Sepolia/Local) β
β βββββββββββββββββββββββββββββββββββββββββββββββββ β
β β TodoList Smart Contract (with Ownership) β β
β β β’ Task Storage (id, title, desc, owner...) β β
β β β’ CRUD Operations with Access Control β β
β β β’ Event Emissions (TaskCreated, etc.) β β
β β β’ getUserTasks() / getMyTasks() β β
β βββββββββββββββββββββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
ββββββββββββββββββββββββββ
β Etherscan Explorer β
β (Transaction History) β
ββββββββββββββββββββββββββ
- Node.js (v16+ recommended)
- npm or yarn
- MetaMask browser extension
- Sepolia testnet ETH (for testnet deployment)
git clone https://github.com/LoganH-web/web3-todo.git
cd web3-todo# Install root dependencies (Hardhat)
npm install
# Install frontend dependencies
cd client
npm install
cd ..Create a .env file in the root directory:
SEPOLIA_URL=https://sepolia.infura.io/v3/YOUR_INFURA_API_KEY
# OR use Alchemy
# SEPOLIA_URL=https://eth-sepolia.g.alchemy.com/v2/YOUR_ALCHEMY_API_KEY
PRIVATE_KEY=your_metamask_private_key_here.env file to version control!
npx hardhat compilenpx hardhat testExpected output: All 40+ tests should pass β
# Terminal 1: Start local Hardhat node
npx hardhat node
# Terminal 2: Deploy contract
npx hardhat run scripts/deploy.js --network localhostnpx hardhat run scripts/deploy.js --network sepoliaCopy the deployed contract address and update client/src/networks.js:
For Local Hardhat:
LOCALHOST: {
chainId: '0x7a69',
chainIdDecimal: 31337,
name: 'Localhost',
contractAddress: 'YOUR_LOCAL_CONTRACT_ADDRESS_HERE', // β Update this
// ...
}For Sepolia Testnet:
SEPOLIA: {
chainId: '0xaa36a7',
chainIdDecimal: 11155111,
name: 'Sepolia Testnet',
contractAddress: 'YOUR_SEPOLIA_CONTRACT_ADDRESS_HERE', // β Update this
// ...
}Important: The contract must be redeployed if you're upgrading from a version before Phase 5, as the Task struct now includes the owner field.
cd client
npm startThe app will open at http://localhost:3000
- Click "Connect Wallet" button in the header
- Approve MetaMask connection request
- Ensure you're on the correct network (Sepolia or Hardhat Local)
- Your wallet address and network will be displayed
- Click the π moon icon (light mode) or βοΈ sun icon (dark mode) below the title
- Theme preference is automatically saved
- Works with system preference if not manually set
- Enter a task title (required, max 200 characters)
- Add an optional description (max 1000 characters)
- Optionally set a due date for the task
- Click "Add Todo"
- Approve the transaction in MetaMask
- Wait for blockchain confirmation
- Task appears in your list with "π€ You" as owner
- Use the "Show only my tasks" checkbox to filter
- See all tasks from all users (unchecked)
- See only tasks you created (checked)
- Owner addresses are shown on each task
- Click "Mark Done" on any pending task (you own)
- Click "Mark Pending" on completed tasks
- Approve the transaction in MetaMask
- Task status updates after confirmation
- β Completed or Pending status is displayed
- Click "Delete" button on any task you own
- Confirm the deletion in the popup
- Approve the transaction in MetaMask
- Task is removed from the blockchain
- Scroll down to see "Recent Transactions" section
- View last 10 transactions with details
- Click "View on Etherscan" to see transaction on block explorer
- Transaction type, description, and timestamp are shown
- Tasks show due date status badges:
- π΄ Red = Overdue
- π‘ Yellow = Due today
- π΅ Blue = Due tomorrow
- π£ Purple = Due within 7 days
- βͺ Gray = Due later
- Only task owners can modify or delete their tasks
- All transactions require MetaMask approval
- Transaction history shows real-time updates
- Network warnings appear if you're on unsupported network
web3-todo/
βββ contracts/
β βββ TodoList.sol # Smart contract with ownership logic
βββ scripts/
β βββ deploy.js # Deployment script
β βββ checkSepolia.js # Network verification
βββ test/
β βββ TodoList.test.js # 40+ comprehensive tests
βββ client/
β βββ src/
β β βββ components/ # π Modular UI components
β β β βββ Header.js # - App header with wallet & theme toggle
β β β βββ TodoForm.js # - Form for creating todos
β β β βββ TodoList.js # - List container with filtering
β β β βββ TodoItem.js # - Individual todo item
β β β βββ TransactionHistory.js # - Activity log
β β β βββ NetworkWarning.js # - Error/warning display
β β β βββ index.js # - Component exports
β β βββ hooks/ # π Custom React hooks
β β β βββ useWeb3.js # - Wallet & provider logic
β β β βββ useContract.js # - Contract interactions
β β β βββ useTransactionHistory.js # - Transaction tracking
β β β βββ useDarkMode.js # - Theme management
β β β βββ index.js # - Hook exports
β β βββ utils/ # π Utility functions
β β β βββ formatters.js # - Address, date, time formatters
β β βββ App.js # Main component (80 lines!)
β β βββ App.css # Styles with dark mode support
β β βββ config.js # Contract ABI & explorer URLs
β β βββ networks.js # Network configurations
β β βββ index.js # React entry point
β βββ public/
β βββ build/ # Production build
β βββ package.json
βββ hardhat.config.js # Hardhat configuration
βββ package.json # Root dependencies
βββ .env # Environment variables (gitignored)
βββ README.md # This file
βββ SPEC.md # Project specification & roadmap
βββ DEPLOYMENT.md # Deployment guide
βββ GAS_OPTIMIZATION.md # Gas optimization notes
βββ PHASE5_IMPLEMENTATION_SUMMARY.md # Phase 5 features
βββ REFACTORING_SUMMARY.md # Code refactoring details
βββ DARK_MODE_IMPLEMENTATION.md # Dark mode guide
βββ PROJECT_COMPLETE.md # Final project summary
The project includes comprehensive test coverage:
npx hardhat test- β Contract deployment and initialization
- β Task creation with validation (CRUD operations)
- β Task completion toggling
- β Task deletion with ownership check
- β Event emissions (TaskCreated, TaskCompleted, TaskDeleted)
- β Ownership validation (only owner can modify/delete)
- β getUserTasks() and getMyTasks() functions
- β Multi-user scenarios and access control
- β Edge cases (empty inputs, invalid IDs, long strings)
- β Integration workflows
- 40+ test cases covering all functionality
- 100% function coverage of smart contract
- Ownership validation tests for security
- Multi-user scenarios with separate task ownership
- Edge case handling for robustness
- Gas optimization validation for cost efficiency
- Open MetaMask
- Click network dropdown at the top
- Select "Sepolia" (enable test networks in Settings if not visible)
- Ensure you have Sepolia ETH for gas fees
Solution: The app automatically detects network changes. If issues persist, click the "π Refresh Network" button in the warning banner.
Solution:
- Ensure you have enough ETH for gas fees
- Verify you're on the correct network (Sepolia or Localhost)
- Check that the contract address in
networks.jsmatches your deployment - Look for specific error messages in MetaMask
Solution:
- This is expected behavior! You can only modify tasks you created
- The owner address is shown on each task
- Check if you're using the correct MetaMask account
- Switch to the account that created the task
Solution:
- Confirm the contract is deployed to the network you're using
- Verify the contract address in
client/src/networks.js - Check that you've connected your wallet
- Important: If you redeployed the contract, update the address in networks.js
Solution:
- You may be using an old contract deployment (before Phase 5)
- Must redeploy the contract to get ownership features
- Follow deployment steps in section 6 above
- Update the contract address in
client/src/networks.js
Solution:
- Ensure tasks were created with the new contract (with ownership)
- Tasks from old contract deployments won't have owner field
- Create a new task to test - it should appear when filtered
Solution:
- Check if localStorage is enabled in your browser
- Not available in private/incognito mode
- Clear browser cache and try again
- Check browser console for localStorage errors
Solution:
- Transaction history only shows transactions made in current session
- History is stored in memory, not localStorage (by design)
- Refresh page clears history
- Transactions still visible on Etherscan via links
Solution:
- Ensure you're on a supported network (Sepolia)
- Local Hardhat network has no block explorer
- Check that transaction was confirmed on blockchain
- Wait a few seconds for Etherscan to index the transaction
- Task editing functionality (update title/description)
- Task categories and tags for organization
- Priority levels (high, medium, low)
- Task sharing and delegation between users
- Subtasks and task dependencies
- IPFS integration for storing large attachments
- Batch operations (toggle/delete multiple tasks)
- Task search and advanced filtering
- Statistics dashboard (completion rate, etc.)
- Email/notification system
- Layer 2 deployment for lower gas fees (Polygon, Arbitrum, Optimism)
- Mobile app (React Native)
- Task templates and recurring tasks
- Team/organization workspaces
- Task comments and collaboration
- β Due dates with visual status indicators
- β Multi-user support with task ownership
- β Dark mode with theme persistence
- β Transaction history and Etherscan integration
- β Responsive design for mobile/tablet/desktop
- β Gas-optimized smart contract
- β Task filtering by owner
- β Real-time event-based updates
- β Professional modular code architecture
// Smart contract now tracks task ownership
struct Task {
uint id;
string title;
string description;
bool completed;
uint dueDate;
address owner; // β New: Tracks task creator
}
// Only owners can modify their tasks
function toggleTaskCompletion(uint _id) public {
require(tasks[i].owner == msg.sender, "Only task owner can modify");
// ...
}Benefits:
- Multi-user support with isolated task management
- Access control prevents unauthorized modifications
- Clear ownership display on each task
- Filter to show only your tasks
Real-time activity log with Etherscan integration:
- Every transaction is tracked and displayed
- Direct links to view on block explorer
- Transaction type, description, timestamp shown
- Network-aware (correct explorer for each network)
- Keeps last 10 transactions visible
Before: 790-line monolithic App.js
After: 80-line orchestrator with:
- 4 custom hooks (useWeb3, useContract, useTransactionHistory, useDarkMode)
- 6 reusable components (Header, TodoForm, TodoList, TodoItem, TransactionHistory, NetworkWarning)
- Utility functions for formatting
- 90% code reduction in main file
Benefits:
- Easy to test each piece independently
- Simple to add new features
- Clear separation of concerns
- Maintainable and scalable
Complete theming system with:
- CSS variables for all colors
- localStorage persistence
- System preference detection
- Smooth transitions (0.3s)
- Toggle button in header
- All components styled for both themes
- Loading states and spinners
- Error handling with user-friendly messages
- Transaction status feedback
- Network warnings and guidance
- Hover effects and animations
- Responsive design (mobile/tablet/desktop)
- Accessibility considerations
Comprehensive guides available:
PHASE5_IMPLEMENTATION_SUMMARY.md- Feature detailsREFACTORING_SUMMARY.md- Architecture breakdownDARK_MODE_IMPLEMENTATION.md- Theme system guidePROJECT_COMPLETE.md- Full project summary
Contributions are welcome! Please feel free to submit a Pull Request.
This project is open source and available under the MIT License.
Built as a comprehensive full-stack blockchain application to demonstrate:
- Smart Contract Development: Solidity with ownership logic and access control
- Web3 Integration: Ethers.js, MetaMask wallet connection, transaction handling
- React Best Practices: Custom hooks, component composition, state management
- Code Architecture: Modular design, separation of concerns, clean code principles
- Testing: 40+ test cases with 100% function coverage
- UI/UX Design: Dark mode, responsive design, user feedback, accessibility
- Documentation: Comprehensive guides and inline comments
- Code Quality: Refactored from 790 to 80 lines in main component
- Security: Input validation, access control, error handling
- Gas Optimization: Efficient contract operations
- User Experience: Real-time updates, transaction history, visual feedback
- β Complete Feature Set: CRUD operations, ownership, history, theming
- β Production Ready: Deployed to Sepolia testnet, fully tested
- β Well Documented: 10+ markdown files covering all aspects
- β Modern Stack: Latest versions of React, Ethers.js, Hardhat
- β Portfolio Quality: Professional presentation and organization
| Metric | Value |
|---|---|
| Lines of Code | ~2,500+ |
| Smart Contract Functions | 7 |
| React Components | 6 |
| Custom Hooks | 4 |
| Test Cases | 40+ |
| Test Coverage | 100% |
| Networks Supported | 2 (Local + Sepolia) |
| Documentation Files | 10+ |
| Code Reduction | 90% (790β80 lines) |
- Hardhat Documentation
- Ethers.js Documentation
- Solidity Documentation
- MetaMask Documentation
- React Documentation
- Complete Feature List
- Deployment Guide
- Refactoring Details
- Phase 5 Features
- Dark Mode Guide
- Project Summary
- Sepolia Etherscan: View Contract
Status: β
Complete & Production-Ready
Completion Date: January 4, 2026
Development Time: ~3 weeks
Phase: 5/5 Complete
- β Phase 1: Smart Contract Foundation
- β Phase 2: Testing & Validation
- β Phase 3: Frontend Integration
- β Phase 4: Testing, Deployment & Finalization
- β Phase 5: Advanced Features & Professional Polish
Built with β€οΈ using Solidity, React, Ethers.js, and Hardhat
A professional-grade decentralized application demonstrating full-stack blockchain development capabilities.