TaskMarket
面向留学生的校园任务市场 —— 发任务、收竞价、用 USDC 在 Coinbase Base 链上非托管 escrow 合约结算。
背景
留学生日常代取快递、跑腿、接机、家教、搬家——基本都在 WeChat 群里走。问题是常态:消息被刷掉、价格在 DM 谈、没有信任信号、没有付款保障。有人接机了拿不到钱;也有人付了定金对方不来。
TaskMarket 从问题的真正难点切入:钱怎么处理。发任务时可选锁定 USDC 到 Coinbase Base 链上的非托管 escrow 合约,竞价排序的 bid book,每任务独立的 Socket.IO 实时聊天,完成后自动结算。平台不持有任何用户资金。
方法
经济核心是 Solidity 合约,不是后端
产品最有辨识度的一块是单文件 Solidity 合约——TaskEscrow.sol,部署在 Coinbase Base。它是 USDC 唯一的流转通道。
生命周期:
- 发起人浏览器端通过 viem 调
approve(USDC)+deposit(taskId, payee, amount) - 选定中标 bid → 订单创建 → 双方实时聊天
- 接单方提交完成证据(文字 + 最多 9 张图)
- 发起人确认 → 合约拆账:
(amount - fee)给接单方,fee给平台。5% 平台费,常量硬上限 20%。 - 争议路径:任一方开 dispute → 管理员 arbiter 调
resolveByOwner(taskId, favorPayee: bool)——一次性二元链上调用,要么走 payer 退款,要么走 payee 放行。没有第三个目的地址。
合约只有 4 个状态(None / Funded / Released / Refunded)且不可升级。Arbiter key 是运营方在链上唯一的特权——能仲裁争议,但不能转走资金、不能突破费率上限、不能给已完结的 task 再注资。
Bid book + value score(不是 first-taker-wins)
每个 task 累积一个 bid book,每条 bid 带价格、ETA、简短 pitch。后端 valueScore 把价格 / 接单方评分 / 完成历史综合排序,发起人不用手工对比十条「我能做 $5」。
Socket.IO 驱动的实时
三个实时 surface:
- 市场列表的 bid heat——新报价不刷页就到
- 在线人数——市场顶部计数器
- 任务级聊天室——bid 中选后开会话,支持 pin / mute / archive / block / report
后台 worker:解决「没人点的时候怎么办」
4 个 worker 是 marketplace 真正的运营性肌肉:
| Worker | 做什么 |
|---|---|
escrowReleaser | 双方都确认了但发起人忘点 release——自动释放链上 escrow |
gasMonitor | 监控 arbiter 钱包 ETH 余额,争议无法仲裁前在管理后台预警 |
orderTimeouts | 中标后接单方一直不启动的订单自动取消 |
taskLifecycle | 扫陈旧任务,回到 OPEN 或标记过期 |
Pinyin 模糊搜索
中文 marketplace 在拉丁键盘上跑,daiquhongbao 必须能搜到 代取红包。用 pinyin-pro 实现,用户不需要切中文输入法。
跟同类「校园任务 app」的差异
| 主流校园任务 app | TaskMarket |
|---|---|
| 固定价格发布 | Bid book(价格 + ETA + pitch),value score 排序 |
| 信任靠感觉 | 星级评分 + 重复历史 + 完成记录 |
| Venmo / e-Transfer 付款 | Base 链上 USDC,锁在非托管合约里 |
| 平台代持资金 | 平台无法移动用户资金;只能在争议时做二元仲裁 |
| 中文名搜不到 | 拼音模糊搜索默认就有 |
| 群聊散落 | 每任务独立 Socket.IO 聊天,pin / mute / archive / block |
结果与教训
Active build,跑在 Base testnet 上。主网上线在等 TaskEscrow.sol 审计。仓库分两边:公开 overview(taskmarket-overview)放截图 / 架构 / 合约逻辑,私有 source repo 放 React app / Express API / Prisma schema / Hardhat 部署脚本。
两条不那么显眼的教训:
钱的处理是产品本身。一个「在 Venmo 上互相信任」的 marketplace 和一个「在 Base 链上非托管 escrow」的 marketplace,平时看起来一样——直到出问题。链上 escrow 不是把产品变成「更好看的论坛 app」,而是让 marketplace 在交易真正发生的那一刻 是 work 的。这才是建在 rails 上的全部意义。
Worker 不是 polish。我最初 scope 这项目时把 escrowReleaser、orderTimeouts 当作「以后再加的打磨」,方向反了。一个没有自动 release 和超时清扫的 marketplace 一周内就堆满死单,新用户一进来觉得是坏的。Worker 是产品 load-bearing 的一部分,不是基础设施杂活。
完整说明见 英文版。