MDT915 Blockchain Implementation Project
CharityFlow is a decentralized application (DApp) built on Ethereum that enables donors to track exactly how their charitable donations are used. Every donation, withdrawal, and proof of work is recorded immutably on the blockchain — making charity fully transparent for the first time.
Report: MDT915_Project_Report.pdf | MDT915_Project_Report.md
| Name | Student ID | Role |
|---|---|---|
| Seif Sid Ali Maloufi | 8718179 | Developer (Smart Contracts, Frontend, Web3, IPFS) |
| Jyldyz Sulaimanova | 9105141 | Report & Theory (Documentation, Research, Academic Writing) |
┌─────────────────────────────────────────────────────────────┐
│ CharityFlow DApp │
├─────────────────┬───────────────────────────────────────────┤
│ Frontend Layer │ React + Vite + Ethers.js │
│ │ Pages: Landing, Campaigns, Detail, │
│ │ Donor Dashboard, Charity Portal │
├─────────────────┼───────────────────────────────────────────┤
│ Web3 Layer │ Ethers.js v6 + MetaMask │
│ │ BrowserProvider → Signer → Contract │
├─────────────────┼───────────────────────────────────────────┤
│ Smart Contract │ CharityDonation.sol (Solidity 0.8.20) │
│ │ Hardhat local / Sepolia testnet │
├─────────────────┼───────────────────────────────────────────┤
│ Storage │ IPFS (Pinata) — images, proofs, receipts │
├─────────────────┼───────────────────────────────────────────┤
│ Blockchain │ Hardhat (31337) / Sepolia (11155111) │
└─────────────────┴───────────────────────────────────────────┘
Donor → MetaMask → CharityDonation Contract → Campaign Wallet
↓
Charity withdraws (with proof)
↓
Platform admin verifies proof
↓
Impact report posted on-chain
| Layer | Technology | Purpose |
|---|---|---|
| Blockchain | Ethereum (Hardhat local/Sepolia) | Immutable ledger |
| Smart Contracts | Solidity 0.8.20 | Business logic |
| Development | Hardhat 2.22.x | Compile, test, deploy |
| Testing | Mocha + Chai + Hardhat Network Helpers | 41 unit tests |
| Frontend | React 18 + Vite 4 | UI |
| Web3 Library | Ethers.js v6 | Blockchain interaction |
| Wallet | MetaMask | User authentication |
| Storage | Pinata (IPFS) | Images, proofs, receipts |
| Routing | React Router v6 | SPA navigation |
| Icons | Lucide React | UI icons |
| Fonts | Inter + JetBrains Mono | Typography |
- Node.js v18+ (v20 recommended for Hardhat)
- npm 9.x or later
- MetaMask browser extension installed
- Pinata account (free) for IPFS uploads
- Sepolia test ETH (from faucet) for testnet deployment
cd "c:\Users\Anigma PC\Desktop\project-blockchain"cd charityflow-hardhat
npm installnpx hardhat compileExpected output:
Compiled 1 Solidity file successfully (evm target: paris).
npx hardhat testExpected output: 41 passing
Open a new terminal and run:
cd charityflow-hardhat
npx hardhat nodeThis starts a local Ethereum node at http://127.0.0.1:8545 with 20 pre-funded test accounts.
Keep this terminal running.
In another terminal:
cd charityflow-hardhat
npx hardhat run scripts/deploy.js --network localhostThis will:
- Deploy the
CharityDonationcontract - Seed 4 demo campaigns with donations, proofs, and impact reports
- Print the contract address
Copy the contract address printed in the output.
cd ../charityflow-frontendEdit .env and paste your contract address:
VITE_CONTRACT_ADDRESS=0x5FbDB2315678afecb367f032d93F642f64180aa3(The default address works if this is your first deployment on a fresh Hardhat node.)
npm install
npm run devOpen your browser at: http://localhost:5173
- Open MetaMask
- Add a custom network:
- Network name:
Hardhat Local - RPC URL:
http://127.0.0.1:8545 - Chain ID:
31337 - Currency symbol:
ETH
- Network name:
- Import a test account using one of the private keys printed by
npx hardhat node
- Add to
charityflow-hardhat/.env:PRIVATE_KEY=your_metamask_private_key ALCHEMY_API_URL=https://eth-sepolia.g.alchemy.com/v2/YOUR_KEY
- Get Sepolia ETH from sepoliafaucet.com
- Deploy:
cd charityflow-hardhat npm run deploy:sepolia - The deploy script auto-updates
charityflow-frontend/.envwith the contract address. - Add
VITE_PINATA_JWTto frontend.envfor IPFS uploads. - Connect MetaMask to Sepolia and use the app.
Live Sepolia contract: 0xE9635eEE0b6EFeB423e9B7aE789C62DB41805F1d
Explorer: Sepolia Etherscan
| Function | Access | Description |
|---|---|---|
createCampaign(title, description, category, imageHash, goalAmount, durationDays) |
Public | Create a new donation campaign |
cancelCampaign(campaignId) |
Charity or Admin | Cancel campaign and enable refunds |
| Function | Access | Description |
|---|---|---|
donate(campaignId, message) |
Public (payable) | Donate ETH to a campaign (2% fee deducted) |
claimRefund(donationId) |
Donor | Claim refund on cancelled campaign |
| Function | Access | Description |
|---|---|---|
withdrawFunds(campaignId, amount, purpose, proofHash) |
Charity | Withdraw with mandatory purpose declaration |
submitProof(campaignId, title, description, fileHash, amountSpent) |
Charity | Upload proof of work (IPFS hash) |
postImpactReport(campaignId, title, content, mediaHashes) |
Charity | Post impact update |
| Function | Access | Description |
|---|---|---|
verifyCharity(address) |
Admin | Mark a charity as verified |
verifyCampaign(campaignId) |
Admin | Mark campaign as verified |
verifyProof(proofId) |
Admin | Verify a submitted proof |
withdrawPlatformFees() |
Admin | Collect accumulated platform fees |
updateFeePercent(newFee) |
Admin | Update platform fee (max 10%) |
transferAdmin(newAdmin) |
Admin | Transfer admin role |
| Function | Description |
|---|---|
getCampaign(id) |
Get full campaign details |
getTotalCampaigns() |
Get total number of campaigns |
getDonorDonations(address) |
Get all donation IDs for a donor |
getCampaignDonations(id) |
Get all donation IDs for a campaign |
getCampaignProofs(id) |
Get all proof IDs for a campaign |
getCampaignWithdrawals(id) |
Get all withdrawal IDs for a campaign |
getCampaignReports(id) |
Get all impact report IDs for a campaign |
getCharityCampaigns(address) |
Get all campaign IDs for a charity |
getCampaignBalance(id) |
Get available (unspent) balance |
- Connect MetaMask (Hardhat local or Sepolia)
- Browse campaigns at
/campaigns - Click a campaign to view details
- Enter ETH amount and click "Donate"
- Confirm in MetaMask
- Go to "My Donations" to track fund usage via the Fund Flow timeline
- Connect MetaMask
- Navigate to "Charity Portal" (
/charity) - Click "Create Campaign" — fill in title, description, category, goal, duration
- After receiving donations, click your campaign and:
- Withdraw Funds: Declare purpose + IPFS receipt hash
- Submit Proof: Upload evidence (photo/invoice/receipt IPFS hash)
- Impact Report: Post updates on outcomes
- Admin wallet is the deployer address (first Hardhat account by default)
- Use Remix IDE or Hardhat console to call admin functions
- Verify charities:
verifyCharity(charityAddress) - Verify proofs:
verifyProof(proofId)
cd charityflow-hardhat
# Run all tests
npx hardhat test
# Run with gas report
npx hardhat test --reporter gas
# Run specific test suite
npx hardhat test --grep "Donations"| Test Suite | Tests | Description |
|---|---|---|
| Deployment | 3 | Contract initialization, admin, fee |
| Campaign Creation | 5 | Creation, validation, edge cases |
| Donations | 7 | Donations, fees, auto-complete, access control |
| Proof of Work | 5 | Submission, verification, access control |
| Withdrawals | 5 | Withdrawals, balance checks, transparency |
| Refunds | 4 | Refund flow, double-refund protection |
| Impact Reports | 2 | Report creation, access control |
| Admin Functions | 7 | All admin operations |
| Deadline Enforcement | 1 | Expired campaign rejection |
| Total | 41 | All passing |
project-blockchain/
├── charityflow-hardhat/ # Blockchain backend
│ ├── contracts/
│ │ └── CharityDonation.sol # Main smart contract
│ ├── scripts/
│ │ └── deploy.js # Deployment + seed script
│ ├── test/
│ │ └── CharityDonation.test.js # 41 unit tests
│ ├── hardhat.config.js # Hardhat configuration
│ └── package.json
│
├── charityflow-frontend/ # React frontend
│ ├── src/
│ │ ├── components/ # Reusable UI components
│ │ │ ├── Logo.jsx # SVG logo (icon + wordmark)
│ │ │ ├── Navbar.jsx # Navigation + wallet connect
│ │ │ └── FundFlowTimeline.jsx # Transparency flow UI
│ │ ├── pages/
│ │ │ ├── Landing.jsx # Home / hero page
│ │ │ ├── CampaignList.jsx # Browse + filter campaigns
│ │ │ ├── CampaignDetail.jsx # Campaign + donation module
│ │ │ ├── DonorDashboard.jsx # Donor history + tracking
│ │ │ └── CharityDashboard.jsx # Charity management portal
│ │ ├── context/
│ │ │ ├── Web3Context.jsx # Wallet + contract state
│ │ │ └── ThemeContext.jsx # Light/dark mode
│ │ └── utils/
│ │ ├── contract.js # Contract helpers, multi-network
│ │ ├── ipfs.js # Pinata upload + gateway URLs
│ │ └── CharityDonationABI.json # ABI from compilation
│ ├── index.html
│ ├── vite.config.js
│ └── package.json
│
├── logo.png # Project logo
└── README.md # This file
- MetaMask only — No WalletConnect; mobile requires MetaMask app.
- No pagination — Campaign list loads all campaigns. For large-scale use, implement on-chain pagination or subgraph indexing with The Graph.
- Admin functions UI — Admin verification actions are not exposed in the UI (must use Hardhat console or Remix IDE directly).
- Node version — Some packages prefer Node 20+; app runs on Node 16–18 with warnings.
- The Graph indexing — Use a subgraph for efficient event-based querying instead of looping through all campaigns
- Multi-token donations — Accept ERC-20 tokens (USDC, DAI) in addition to ETH
- DAO governance — Allow token holders to vote on which charities get verified
- Automated verification oracle — Use Chainlink oracles to automate proof verification
- Mobile app — React Native version with WalletConnect for mobile donors
- Mainnet deployment — Production deployment with public block explorer links
- Email notifications — Off-chain notification service when proofs are verified or impact reports posted
- Ethereum/Solidity: CryptoZombies
- Hardhat: Official Hardhat Tutorial
- Ethers.js: Ethers.js Documentation
- OpenZeppelin patterns referenced for modifier and access control design
- React: React Documentation
- MetaMask: MetaMask Developer Docs
MIT License — Open source for educational purposes.
CharityFlow — Every donation, fully traceable. Built for MDT915 Blockchain Practitioner Course.