A decentralized crowdfunding application built with Solidity, Hardhat, Next.js, and ethers.js. This DApp allows users to create campaigns, contribute funds, add rewards, and manage withdrawals/refunds in a transparent, blockchain-based system.
Live Application: https://crowdfundiing-dapp.vercel.app
- Campaign Management: Create campaigns with custom goals, timelines, and metadata URIs
- Reward System: Add tiered rewards to campaigns with minimum contribution requirements and limited quantities
- Contributions: Pledge ETH to campaigns with optional reward selection
- Smart Withdrawals: Campaign creators can withdraw funds when goals are met and campaigns have ended
- Automatic Refunds: Contributors can get refunds if campaigns fail to reach their goals
- Guest Mode: Browse campaigns and view project details without connecting a wallet
- Sample Campaigns: Pre-loaded sample campaigns for demonstration purposes
- Wallet Integration: Seamless MetaMask connection with automatic network detection
- User Dashboard: Track contributions, created campaigns, and eligible rewards
- My Contributions: View all campaigns you've contributed to with contribution amounts
- My Campaigns: Manage campaigns you've created with quick access to rewards and statistics
- My Rewards: Track reward eligibility, claimed status, and missed rewards
- Real-time Updates: Live progress bars, countdown timers, and status badges
- Error Handling: Comprehensive error handling with user-friendly messages for insufficient funds, transaction failures, and network issues
- Balance Validation: Pre-transaction balance checks to prevent failed transactions
- Multi-network Support: Automatic contract address detection for Sepolia testnet and localhost
- Type Safety: Full TypeScript coverage throughout the application
- Responsive Design: Works seamlessly on desktop, tablet, and mobile devices
- Toast Notifications: User-friendly feedback for all transactions and errors
- Loading States: Smooth loading indicators throughout the application
- Solidity 0.8.28
- Hardhat 2.10.0
- OpenZeppelin (ReentrancyGuard)
- Next.js 15.5.2 (App Router)
- React 19.1.0
- TypeScript 5
- Tailwind CSS 4.1.12
- ethers.js 6.15.0
- react-hot-toast 2.6.0
- Node.js >= 18.0.0
- npm or yarn
- MetaMask browser extension
- Hardhat (for local blockchain development)
git clone https://github.com/AlexKalll/crowd-funding-DApp.git
cd crowd-funding-DAppInstall root dependencies (for Hardhat):
npm installInstall frontend dependencies:
cd frontend
npm install
cd ..In the root directory, start the Hardhat network:
npx hardhat nodeThis will:
- Start a local Ethereum node on
http://127.0.0.1:8545 - Provide 20 test accounts with 10,000 ETH each
- Display the accounts and private keys in the terminal
Keep this terminal window open.
In a new terminal window, deploy the contract to the local network:
npx hardhat run scripts/deploy.ts --network localhostThis will:
- Deploy the
Crowdfund.solcontract - Output the contract address
- Create or update
frontend/src/constants/deployments.localhost.json
Verify the deployment file contains the contract address:
{
"Crowdfund": {
"address": "0x...your-contract-address..."
}
}-
Open MetaMask extension
-
Click the network dropdown (top center)
-
Select "Add Network" → "Add a network manually"
-
Enter the following:
- Network Name: Hardhat Localhost
- RPC URL: http://127.0.0.1:8545
- Chain ID: 31337
- Currency Symbol: ETH
- Block Explorer: (leave empty)
-
Import test accounts:
- From the Hardhat node terminal, copy private keys
- In MetaMask: Settings → Security & Privacy → Import Account
- Paste private keys to import test accounts
In a new terminal window:
cd frontend
npm run devThe app will be available at http://localhost:3000
- Open
http://localhost:3000in your browser - Click "Connect MetaMask" in the top-right corner
- Select your MetaMask account
- Approve the connection
Alternatively, click "Continue as Guest" to browse campaigns without connecting a wallet.
- Connect your wallet
- Click "Create Campaign" in the sidebar
- Fill in the form:
- Goal: e.g., 10 ETH
- Start Time: e.g., 1 hour from now
- End Time: e.g., 7 days from start time
- Metadata URI: Project description or link
- Submit the transaction
- Go to "My Campaigns" in the sidebar
- Click on your campaign
- Click "Add Reward" button
- Fill in reward details:
- Title: e.g., "Early Bird Special"
- Description: e.g., "Get exclusive access"
- Minimum Contribution: e.g., 0.5 ETH
- Quantity Available: e.g., 10
- Save the reward
Note: Rewards can only be added before the campaign starts.
- Switch to another MetaMask account (or use a different account)
- Browse campaigns in the "Browse Campaigns" tab
- Click on a campaign card to view details
- Enter contribution amount
- Select a reward tier (if available)
- Submit the pledge
- Wait for campaign to end
- Ensure campaign goal was met
- Switch to creator account
- View campaign details
- Click "Withdraw Funds"
- Find a campaign that failed to reach its goal
- Ensure the campaign has ended
- View campaign details
- Click "Request Refund"
- Create a
.envfile in the root directory:
SEPOLIA_RPC_URL=https://sepolia.infura.io/v3/YOUR_INFURA_KEY
PRIVATE_KEY=your_private_key_here # the metamask account private key which have a sepolia eth
- Deploy to Sepolia:
npx hardhat run scripts/deploy.ts --network sepoliaThe deployment script will automatically save the contract address to frontend/src/constants/deployments.sepolia.json.
- Install Vercel CLI:
npm install -g vercel- Login to Vercel:
vercel login- Navigate to frontend directory:
cd frontend- Deploy:
vercel- Follow the prompts:
- Set up and deploy? Yes
- Which scope? (select your account)
- Link to existing project? No (or Yes if updating)
- Project name? (enter a name or press Enter)
- Directory?
frontend(or.if already in frontend) - Override settings? No
- Push to GitHub:
git add .
git commit -m "Prepare for deployment"
git push origin main-
Import Project in Vercel:
- Go to vercel.com
- Sign in with GitHub
- Click "Add New Project"
- Import your repository
-
Configure Project:
- Root Directory:
frontend - Framework Preset: Next.js
- Build Command:
npm run build(or leave default) - Output Directory:
.next(or leave default) - Install Command:
npm install
- Root Directory:
-
Deploy:
- Click "Deploy"
- Wait for build to complete
- Access your live URL
Docker allows you to run the application in a container, making it easy to deploy anywhere.
docker build -t crowdfunding-dapp .docker run -p 3000:3000 crowdfunding-dappThe app will be available at http://localhost:3000
For easier management:
docker-compose upThis will build and run the frontend container automatically.
Note: For local development, you still need to run Hardhat node separately as it's not included in the Docker setup.
The project includes GitHub Actions workflows that automatically:
-
Test Smart Contracts (
.github/workflows/ci.yml):- Runs on every push and pull request
- Compiles contracts
- Runs test suite
- Ensures code quality
-
Lint and Build Frontend (
.github/workflows/ci.yml):- Runs on every push and pull request
- Checks code style with ESLint
- Verifies the frontend builds successfully
-
Deploy Contract (
.github/workflows/deploy-contract.yml):- Manual workflow for deploying to Sepolia
- Requires GitHub Secrets to be set up:
SEPOLIA_RPC_URL: Your Sepolia RPC endpointPRIVATE_KEY: Your deployment account private key
To use the deployment workflow:
-
Go to your GitHub repository
-
Click Settings → Secrets and variables → Actions
-
Click "New repository secret"
-
Add:
- Name:
SEPOLIA_RPC_URL, Value: Your Sepolia RPC URL - Name:
PRIVATE_KEY, Value: Your private key (with Sepolia ETH)
- Name:
-
Go to Actions tab → Deploy Contract to Sepolia → Run workflow
crowd-funding-DApp/
├── contracts/
│ └── Crowdfund.sol # Main smart contract
├── scripts/
│ └── deploy.ts # Deployment script
├── test/
│ └── Crowdfund.test.ts # Contract tests
├── frontend/
│ ├── app/
│ │ ├── page.tsx # Main page component
│ │ ├── layout.tsx # Root layout
│ │ └── globals.css # Global styles
│ ├── src/
│ │ ├── components/
│ │ │ ├── WalletConnect.tsx
│ │ │ ├── CampaignCard.tsx
│ │ │ ├── CreateCampaignModal.tsx
│ │ │ ├── CampaignDetailModal.tsx
│ │ │ └── AddRewardModal.tsx
│ │ ├── lib/
│ │ │ └── web3.ts # Web3 utilities
│ │ ├── utils/
│ │ │ ├── errorHandler.ts # Error handling utilities
│ │ │ └── userMapping.ts # User name mapping
│ │ ├── constants/
│ │ │ ├── Crowdfund.json # Contract ABI
│ │ │ ├── deployments.localhost.json
│ │ │ ├── deployments.sepolia.json
│ │ │ └── sampleCampaigns.ts
│ │ └── types.ts # TypeScript interfaces
│ ├── package.json
│ └── next.config.ts
├── .github/
│ └── workflows/
│ ├── ci.yml # CI workflow
│ └── deploy-contract.yml # Deployment workflow
├── hardhat.config.ts
├── Dockerfile # Docker configuration
├── docker-compose.yml # Docker Compose configuration
├── package.json
└── README.md
The hardhat.config.ts supports multiple networks:
localhost: Local development network (Chain ID: 31337)sepolia: Sepolia testnet (Chain ID: 11155111)mumbai: Polygon Mumbai testnet (Chain ID: 80001)
To configure testnet deployment, create a .env file with:
SEPOLIA_RPC_URL=https://sepolia.infura.io/v3/YOUR_INFURA_KEY
MUMBAI_RPC_URL=https://polygon-mumbai.infura.io/v3/YOUR_INFURA_KEY
PRIVATE_KEY=your_private_key_here
The frontend automatically detects the connected network and uses the appropriate contract address:
- Sepolia testnet: Uses
deployments.sepolia.json - Localhost/Hardhat: Uses
deployments.localhost.json
The application includes comprehensive error handling for common blockchain transaction errors:
- Insufficient Funds: Detailed messages showing required amount, current balance, and shortfall
- Transaction Rejection: Clear notification when user rejects transaction
- Network Errors: Helpful messages for connection issues
- Gas Estimation Failures: Pre-flight checks to catch errors before submission
- Contract Reverts: User-friendly messages for campaign-specific errors (inactive, not creator, etc.)
All errors are displayed with actionable feedback and extended toast durations for better readability.
# Compile contracts
npx hardhat compile
# Run tests
npx hardhat test
# Deploy to localhost
npx hardhat run scripts/deploy.ts --network localhost
# Deploy to Sepolia
npx hardhat run scripts/deploy.ts --network sepolia# Start development server
cd frontend
npm run dev
# Build for production
npm run build
# Start production server
npm start
# Run linter
npm run lint"Contract not available" error
- Ensure Hardhat node is running
- Verify contract is deployed
- Check deployment JSON file has correct address
- Ensure you're connected to the correct network in MetaMask
MetaMask connection fails
- Check network is set to localhost (Chain ID: 31337) for local development
- Ensure MetaMask is unlocked
- Try refreshing the page
- Check browser console for errors
Insufficient funds error
- Verify you have enough ETH in your wallet
- Remember you need ETH for both the transaction amount and gas fees
- For testnets, use a faucet to get test ETH
Build errors on Vercel
- Check Node.js version (should be >= 18)
- Verify all dependencies are in
package.json - Check build logs for specific errors
- Ensure TypeScript/ESLint errors are resolved before pushing
Transaction fails silently
- Check browser console for error messages
- Verify network connection
- Ensure contract address is correct for the network
- Check MetaMask transaction history
Docker build fails
- Ensure Docker is installed and running
- Check that Node.js version in Dockerfile matches your local version
- Verify all dependencies are correctly listed in package.json
- Check Docker logs for specific error messages
GitHub Actions fails
- Ensure all tests pass locally first
- Check that your code follows linting rules
- Verify all dependencies are in package.json
- Check Actions tab for detailed error logs
Contributions are welcome! Please see CONTRIBUTING.md for guidelines on how to contribute to this project.
For questions, issues, or feature requests, please open an issue on GitHub.