shezanyo/Orpon
GitHub: shezanyo/Orpon
Orpon 是一个为孟加拉国构建的加密可验证众筹平台,通过 SHA-256 哈希链账本和 Polygon 区块链锚定技术解决在线捐赠的信任与透明度问题。
Stars: 0 | Forks: 0
# Orpon
### 透明与安全的众筹
[](https://orpon.me)
[](https://thankful-sea-0f5fbd000.7.azurestaticapps.net)
[](https://orpon-backend-api-sea.azurewebsites.net/api/health)
[](LICENSE)
## 概述
**Orpon** 是一个为孟加拉国社区构建的捐赠透明平台。它允许个人为他们关心的事业创建筹款活动——如医疗紧急情况、灾难救援、教育或社区项目——并通过当地流行的支付方式(如 bKash、Nagad 和银行卡)接受捐赠。
### 解决的问题
信任是孟加拉国在线捐赠的最大障碍。捐赠者往往无法核实他们的资金是如何使用的。Orpon 通过一个**防篡改的、区块链风格的哈希链**来解决这个问题,该哈希链以加密方式链接每一条捐赠记录,并可选择将账本哈希锚定到 **Polygon Amoy** 测试网——为任何第三方提供可证明的保证,确保捐赠历史未被篡改。
### 目标用户
- 希望放心捐赠的**个人捐赠者**
- 需要透明、可验证的记录以建立信誉的**活动组织者**
- 需要实时监督和完整性验证的**平台管理员**
- 寻求本地语言友好型筹款工具的**社区团体和非政府组织 (NGO)**
## 功能
### 用户认证
- 安全的注册和登录,使用 **bcrypt 哈希密码** 和 **JWT token**
- 限速认证 endpoint 以防止暴力破解攻击
- **忘记密码** 流程,提供安全、有时限的重置链接(15分钟过期)
- 通过 SMTP 发送带品牌标识的密码重置电子邮件(本地测试使用 Ethereal.email 作为后备)
### 活动创建与管理
- 丰富的活动创建表单:标题、描述、故事、类别、目标金额和持续时间
- 最多上传 **3 张活动图片**(存储在 Cloudinary 上,通过 CDN 提供)
- 活动详情页面上提供 GoFundMe 风格的**图片滑块轮播**
- 活动类别:医疗、教育、灾难救援、社区
- 组织者可以通过 **我的活动** 控制面板管理和删除他们自己的活动
### 捐赠
- 对访客友好:捐赠者可以选择**匿名、私密或公开**进行捐赠
- 区块链风格的 **SHA-256 哈希链**:每条捐赠记录都包含 `previous_hash` 和 `current_hash`,形成一个防篡改的账本
- 直接记录捐赠并跟踪支付方式
### 支付集成(沙盒)
- **bKash** – 孟加拉国领先的 MFS 提供商(代币化沙盒)
- **Nagad** – 带有回调验证的沙盒支付流程
- **SSLCommerz** – 银行卡支付沙盒(VISA/MasterCard),带有成功/失败/取消回调
- 为每个支付网关提供专用的 Webhook/回调处理器,以可靠地记录支付状态
### 捐赠追踪与公开账本
- 公开的 `/transactions` endpoint 公开完整的捐赠账本
- 每笔交易都显示金额、显示名称(尊重隐私设置)、时间戳和哈希值
- 任何用户都可以独立重新计算哈希值以验证账本的完整性
### 评论
- 已认证的用户可以在任何活动上发布、编辑和删除评论
- 公开阅读权限,允许访客在不登录的情况下查看更新
### 捐赠者排行榜
- 公开排行榜,对最慷慨的具名捐赠者进行排名
- 匿名和私密捐赠者被排除在排名之外,以保护隐私偏好
### 数据分析控制面板(活动所有者)
- 单项活动的捐赠总额、捐赠者人数和进度可视化
- 所有者只能查看他们创建的活动的分析数据
### 管理员控制面板
- 汇总统计数据:活动总数、捐赠总额、用户数和筹集金额
- 全面查看所有活动、捐赠和已注册的用户
- **完整性验证**:实时重新计算并比较哈希链
- 将用户提升为管理员角色
- 系统活动日志
### 区块链锚定
- 通过 Solidity 智能合约将批处理的捐赠哈希锚定到 **Polygon Amoy** 测试网
- 锚定是可选的(当缺少凭证时会优雅地禁用)
- 公开的 `/api/anchors/history` endpoint 公开所有锚定记录
- 可从控制面板触发管理员手动锚定
### 验证与信任功能
- 活动 `is_verified` 标志(可由管理员设置)
- 对用户账户的唯一 NID 和手机号约束,以减少重复注册
- 每个 API 响应都带有 Helmet.js HTTP 安全标头
- 严格的 CORS 白名单(仅限 `orpon.me`、`www.orpon.me` 和已配置的来源)
## 技术栈
### 前端
| 技术 | 用途 |
|---|---|
| React 19 | UI 库 |
| React Router v6 | 客户端路由 |
| Vite 8 | 构建工具与开发服务器 |
| Tailwind CSS 3 | 实用优先的样式框架 |
| Lucide React | 图标集 |
| qrcode.react | 二维码生成 |
| Plus Jakarta Sans (Google Fonts) | 排版字体 |
### 后端
| 技术 | 用途 |
|---|---|
| Node.js + Express 5 | REST API 服务器 |
| Helmet.js | HTTP 安全标头 |
| Morgan | HTTP 请求日志 |
| Nodemailer | 事务性电子邮件(密码重置) |
| Multer | 多部分图片上传处理 |
| bcrypt | 密码哈希 |
| jsonwebtoken | 无状态 JWT 认证 |
| uuid | 唯一 ID 生成 |
| crypto (Node 内置) | SHA-256 哈希链 |
| ethers.js v6 | Polygon 区块链交互 |
### 数据库
| 技术 | 用途 |
|---|---|
| Azure SQL Database (MSSQL) | 主关系型数据库 |
| mssql (npm) | SQL Server 驱动程序 |
| Redis(可选) | 会话/缓存层(回退到内存模式) |
### 云与存储
| 服务 | 用途 |
|---|---|
| Azure App Service | 后端托管(东南亚区域) |
| Azure Static Web Apps | 前端托管 + 全球 CDN |
| Cloudinary | 活动图片存储与交付 |
### 支付网关(沙盒)
| 网关 | 方式 |
|---|---|
| bKash | 孟加拉国 MFS(代币化 API) |
| Nagad | 孟加拉国 MFS(沙盒) |
| SSLCommerz | 银行卡支付(VISA/MC 沙盒) |
### 区块链
| 组件 | 详情 |
|---|---|
| 网络 | Polygon Amoy 测试网 |
| 合约 | 存储批量哈希的自定义 Solidity 合约 |
| 库 | ethers.js v6 |
### DevOps / CI-CD
| 工具 | 用途 |
|---|---|
| GitHub Actions | 自动化 CI/CD 管道 |
| Azure Static Web Apps Deploy Action | 前端部署 |
| Azure Web Apps Deploy Action | 后端部署 |
## 截图
以下是一些展示 Orpon 平台 UI/UX、透明捐赠流程以及管理完整性验证器的截图。
### 🏠 主页
*具有高影响力的英雄横幅、已验证的紧急活动网格、实时平台统计数据递增,以及信任高亮说明。*

### 🔍 探索活动
*活动网格布局,具有搜索功能和基于类别的响应式筛选器(全部、医疗、教育、灾难救援、社区)。*

### 🛡️ 管理控制面板与完整性验证
*允许平台管理员审查统计数据、检查系统活动日志、管理用户,以及对本地 SHA-256 哈希链账本与 Polygon 区块链锚点进行实时审计。*

## 安装说明
### 前置条件
- **Node.js** v20 或更高版本
- **npm** v9+
- 一个 **Azure SQL** 数据库(或任何兼容 MSSQL 的服务器)
- 一个 **Cloudinary** 账户(免费版即可)
- (可选)**Redis** 实例
### 1. 克隆仓库
```
git clone https://github.com/
/Orpon.git
cd Orpon
```
### 2. 后端设置
```
cd backend
npm install
cp .env.example .env
# 使用你的凭据编辑 .env(参见 Environment Variables 部分)
```
### 3. 数据库设置
针对您的 Azure SQL(或 MSSQL)数据库运行提供的 SQL schema:
```
# 使用 sqlcmd
sqlcmd -S .database.windows.net -U -P -d donation_system -i schema.sql
# 或者将 schema.sql 的内容粘贴到 Azure Data Studio / SSMS 中
```
该 schema 创建了四个表:`users`、`campaigns`、`donations`、`comments`。
### 4. 前端设置
```
cd ../frontend
npm install
cp .env.example .env
# 如果你想指向远程后端,请设置 VITE_API_URL
```
## 环境变量
### 后端 (`backend/.env`)
```
# Server
PORT=5000
# URL(必须与支付回调部署的 URL 匹配)
BACKEND_URL=http://localhost:5000
FRONTEND_URL=http://localhost:5173
# Azure SQL Database
DB_HOST=your-server.database.windows.net
DB_USER=your_username
DB_PASSWORD=your_password
DB_NAME=donation_system
DB_PORT=1433
DB_TRUST_CERT=false
# Redis(可选 – 回退到内存中)
USE_REDIS=false
REDIS_URL=redis://localhost:6379
# Security
JWT_SECRET=
# Cloudinary(可选 – 全部设置或均不设置)
CLOUDINARY_CLOUD_NAME=your_cloud_name
CLOUDINARY_API_KEY=your_api_key
CLOUDINARY_API_SECRET=your_api_secret
# bKash Sandbox
BKASH_USERNAME=your_bkash_sandbox_username
BKASH_PASSWORD=your_bkash_sandbox_password
BKASH_APP_KEY=your_bkash_app_key
BKASH_APP_SECRET=your_bkash_app_secret
BKASH_BASE_URL=https://tokenized.sandbox.bka.sh/v1.2.0-beta
# SSLCommerz Sandbox
SSLCOMMERZ_STORE_ID=your_store_id
SSLCOMMERZ_STORE_PASSWORD=your_store_password
SSLCOMMERZ_BASE_URL=https://sandbox.sslcommerz.com
# SMTP(用于密码重置邮件)
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USER=your_email@gmail.com
SMTP_PASS=your_gmail_app_password
SMTP_FROM=your_email@gmail.com
# Blockchain(可选 – Polygon Amoy)
POLYGON_RPC_URL=https://rpc-amoy.polygon.technology/
WALLET_PRIVATE_KEY=0x...
CONTRACT_ADDRESS=0x...
```
### 前端 (`frontend/.env`)
```
# 本地开发时保持未设置(自动检测 localhost)
# 用于生产构建或使用远程后端时设置
VITE_API_URL=http://localhost:5000/api
```
## 在本地运行
### 启动后端
```
cd backend
npm run dev # uses nodemon for hot-reload
# 或
npm start # production-mode start
```
后端运行在 **http://localhost:5000**。健康检查:`GET /api/health`
### 启动前端
```
cd frontend
npm run dev
```
前端开发服务器运行在 **http://localhost:5173**。
### 为生产环境构建前端
```
cd frontend
npm run build # outputs to frontend/dist/
npm run preview # local preview of production build
```
## 项目结构
```
Orpon/
├── .github/
│ └── workflows/
│ ├── azure-static-web-apps-*.yml # Frontend CI/CD (GitHub Actions)
│ └── azure-web-app-backend.yml # Backend CI/CD (GitHub Actions)
│
├── backend/
│ ├── config/ # DB connection & env validation
│ ├── controllers/ # Route handlers (auth, campaign, donation, payment, admin, ...)
│ │ ├── adminController.js
│ │ ├── anchorController.js # Blockchain anchoring
│ │ ├── authController.js # Register, login, password reset
│ │ ├── campaignController.js
│ │ ├── commentController.js
│ │ ├── donationController.js
│ │ ├── leaderboardController.js
│ │ └── paymentController.js # bKash, Nagad, SSLCommerz
│ ├── middleware/
│ │ ├── adminMiddleware.js # Role guard (admin/super_admin)
│ │ ├── authMiddleware.js # JWT verification
│ │ └── rateLimiter.js # Auth rate limiting
│ ├── routes/ # Express route definitions (one file per resource)
│ ├── services/
│ │ ├── blockchainService.js # Polygon Amoy anchoring via ethers.js
│ │ ├── emailService.js # Nodemailer / Ethereal fallback
│ │ └── hashService.js # SHA-256 hash computation
│ ├── schema.sql # Azure SQL (T-SQL) database schema
│ ├── server.js # Express app entry point
│ └── .env.example # Environment variable template
│
├── frontend/
│ ├── public/ # Static assets (favicon, etc.)
│ └── src/
│ ├── assets/ # Images & SVGs
│ ├── components/
│ │ ├── layout/ # Navbar, Footer
│ │ └── ui/ # Reusable UI components
│ ├── context/ # AuthContext (global auth state)
│ ├── data/ # Fallback mock campaign data
│ ├── pages/ # One file per route/page
│ │ ├── AdminDashboard.jsx
│ │ ├── CampaignAnalytics.jsx
│ │ ├── CampaignDetail.jsx
│ │ ├── CreateCampaign.jsx
│ │ ├── Donate.jsx
│ │ ├── ForgotPassword.jsx
│ │ ├── Home.jsx
│ │ ├── Leaderboard.jsx
│ │ ├── Login.jsx
│ │ ├── MyCampaigns.jsx
│ │ ├── NagadSandbox.jsx # Nagad sandbox redirect handler
│ │ ├── PaymentSuccess/Fail/Cancel.jsx
│ │ ├── Profile.jsx
│ │ └── ResetPassword.jsx
│ ├── utils/
│ │ ├── api.js # Centralised API helper functions
│ │ └── format.js # Currency, slug, percentage helpers
│ ├── App.jsx # Root component & router setup
│ └── main.jsx # React entry point
│
├── staticwebapp.config.json # Azure SPA routing config
├── schema.sql # (duplicate) Root-level schema reference
└── README.md
```
## API 概述
所有 endpoint 都带有前缀 `/api`。
### 认证 — `/api/auth`
| 方法 | 路径 | 认证 | 描述 |
|--------|------|------|-------------|
| `POST` | `/register` | — | 注册新用户 |
| `POST` | `/login` | — | 登录,接收 JWT |
| `GET` | `/me` | ✅ JWT | 获取已认证用户的个人资料 |
| `POST` | `/forgot-password` | — | 请求密码重置电子邮件 |
| `GET` | `/reset-password/verify` | — | 验证重置 token 的有效性 |
| `POST` | `/reset-password` | — | 使用有效的 token 设置新密码 |
### 活动
| 方法 | 路径 | 认证 | 描述 |
|--------|------|------|-------------|
| `GET` | `/campaigns` | — | 列出所有活动 |
| `POST` | `/campaign/create` | ✅ JWT | 创建活动(最多 3 张图片) |
| `DELETE` | `/campaign/:id` | ✅ JWT | 删除自己的活动 |
### 捐赠与支付
| 方法 | 路径 | 认证 | 描述 |
|--------|------|------|-------------|
| `POST` | `/donate` | — | 记录直接捐赠 |
| `GET` | `/transactions` | — | 所有捐赠的公开账本 |
| `POST` | `/payment/bkash/initiate` | — | 启动 bKash 沙盒支付 |
| `GET` | `/payment/bkash/callback` | — | bKash 回调处理器 |
| `POST` | `/payment/card/initiate` | — | 启动 SSLCommerz 银行卡支付 |
| `POST` | `/payment/card/success` | — | SSLCommerz 成功回调 |
| `POST` | `/payment/card/fail` | — | SSLCommerz 失败回调 |
| `POST` | `/payment/card/cancel` | — | SSLCommerz 取消回调 |
| `POST` | `/payment/nagad/initiate` | — | 启动 Nagad 沙盒支付 |
| `POST` | `/payment/nagad/callback` | — | Nagad 支付验证 |
| `POST` | `/payment/nagad/cancel` | — | Nagad 取消回调 |
### 评论
| 方法 | 路径 | 认证 | 描述 |
|--------|------|------|-------------|
| `GET` | `/campaign/:id/comments` | — | 获取活动的评论 |
| `POST` | `/campaign/:id/comments` | ✅ JWT | 发表评论 |
| `PUT` | `/comment/:id` | ✅ JWT | 编辑自己的评论 |
| `DELETE` | `/comment/:id` | ✅ JWT | 删除自己的评论 |
### 排行榜
| 方法 | 路径 | 认证 | 描述 |
|--------|------|------|-------------|
| `GET` | `/leaderboard` | — | 顶级具名捐赠者(不包括匿名者) |
### 管理员 — 角色:`admin` 或 `super_admin`
| 方法 | 路径 | 认证 | 描述 |
|--------|------|------|-------------|
| `GET` | `/admin/stats` | ✅ 管理员 | 全平台统计数据 |
| `GET` | `/admin/campaigns` | ✅ 管理员 | 所有活动 |
| `GET` | `/admin/donations` ✅ 管理员 | 所有捐赠 |
| `GET` | `/admin/logs` | ✅ 管理员 | 系统活动日志 |
| `GET` | `/admin/verify` | ✅ 管理员 | 哈希链完整性检查 |
| `GET` | `/admin/users` | ✅ 管理员 | 所有已注册的用户 |
| `POST` | `/admin/make-admin` | ✅ 管理员 | 将用户提升为管理员 |
### 区块链锚点
| 方法 | 路径 | 认证 | 描述 |
|--------|------|------|-------------|
| `GET` | `/anchors/history` | — | 来自 Polygon 的公开锚点记录 |
| `GET` | `/anchors/status` | ✅ 管理员 | 区块链连接状态 |
| `POST` | `/anchors/manual` | ✅ 管理员 | 触发手动锚定交易 |
## 部署
Orpon 使用 GitHub Actions CI/CD 部署在 **Microsoft Azure** 上。
### 前端
- 托管在 **Azure Static Web Apps**(东南亚)
- 每次推送到 `development` 分支时**自动部署**
- 构建:`cd frontend && npm ci && npm run build`(Vite → `frontend/dist/`)
- `staticwebapp.config.json` 配置了 SPA 回退路由,以便 React Router 链接在直接导航时能正常工作
### 后端
- 托管在 **Azure App Service** (`orpon-backend-api-sea`)
- 每次推送到 `development` 分支时**自动部署**
- 部署包:`deploy.zip`(后端源代码,不包含 `node_modules` 和 `.env`)
- App Service 通过 `package.json` 中的 `start` 脚本运行 `node server.js`
- 所有环境变量均配置为 Azure 门户中的**应用程序设置**(绝不会包含在 zip 文件中)
### 自定义域名
- 上线于 **[https://orpon.me](https://orpon.me)** — 通过 Azure Static Web Apps 自定义域名进行配置
### 关键 Azure 资源
| 资源 | 名称 |
|---|---|
| Static Web App | `thankful-sea-0f5fbd000` |
| App Service(后端) | `orpon-backend-api-sea` |
| SQL Server | `orpon-sql-server.database.windows.net` |
| 资源组 | `OrponRG` |
## 贡献者
| 贡献者 |
|---|
| shezanyo |
| mibon201101 |
| ssunjana |
| aanik |
| rrumi25800 |
## 许可证
该项目基于 **MIT License** 发布。
```
MIT License
Copyright (c) 2025 Orpon Contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
```
标签:MITM代理, Syscall, Web开发, 众筹平台, 区块链, 哈希链, 搜索引擎查询, 支付集成, 自定义脚本, 透明化/可验证性