Skip to content

Latest commit

 

History

9 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 

Repository files navigation

MonadAuction — 链上 Commit-Reveal 密封竞价拍卖应用

基于 Monad 高性能 EVM 链的密封竞价拍卖应用。买家在 5 轮中先提交价格哈希、再揭露原值,全程链上、无可作弊、无中心化数据库。黑金风格的 Next.js 前端,所有交互即交易。

Monad License


✨ 项目简介

传统拍卖中出价公开、易被狙击("狙击"指看到别人出价后临时加价)。本项目的做法是 Commit-Reveal(提交-揭露)

  1. 提交阶段:买家只把 keccak256(price, bidder, salt) 这个哈希上链,价格本身不公开展示
  2. 揭露阶段:买家再上链公布 (price, salt),合约用同样的哈希函数验证一致性;
  3. 任何人都无法在提交阶段得知别人的真实出价,从根本上消除狙击。

所有创建、报名、出价、比价、结算动作都是链上交易;前端仅在浏览器 localStorage 保存 salt 与价格秘密,用于揭露阶段本地拼装,绝不上传服务器。


🎯 核心特性

  • 5 轮密封竞价:每轮 30s 提交哈希 → 30s 揭露原值,递进式逼近成交价。
  • 待竞拍物品展示横廊:列表页底部内置 12 件黑金风物品图鉴(⌚百达翡丽 / 💎粉钻 / 🖼️加密艺术 / 🏎️法拉利 …),纯前端渲染,未连钱包也能浏览
  • 链上活动日志useWatchContractEvent + 历史 getLogs,把报名 / 出价 / 比价 / 成交 / 结算事件串成实时时间线。
  • 每轮实时报价榜:揭露期按已揭露报价排序并标出当前领先者。
  • 我的参与状态条 + 交易状态 Toast:pending 转圈、成功带 Monad 浏览器链接、失败红字详情。
  • 黑金视觉语言:暗色网格纹理 + 顶部金色光带 + 渐变标题 + 阶段色卡片边框 + 悬停展开(最近成交价 / 最高出价)。
  • 房间页物品大卡头图:巨型 emoji 水印 + 物品名 + 「🎯 正在竞拍」标识,操作台与结算面板均点明当前竞拍物品。

🖼️ 界面预览

竞拍场列表(含待竞拍物品横廊) 房间页(已结算) 房间页(进行中)
首页 房间-已结算 房间-进行中

🧱 技术栈

技术
智能合约 Solidity ^0.8.24 · Hardhat · OpenZeppelin 风格安全校验
前端 Next.js 14(App Router)· React 18 · TypeScript · Tailwind CSS
链上交互 wagmi v2 · viem · TanStack Query
钱包 MetaMask(注入式 injected connector)
数据 全部来自链上事件,无后端数据库

📁 目录结构

monad-auction/
├── contracts/                 # Hardhat 合约工程
│   ├── contracts/MonadAuctionHouse.sol   # 密封竞拍核心合约
│   ├── scripts/deploy.js                  # 部署脚本
│   ├── test/*.test.js                     # 16 个单元测试
│   └── hardhat.config.js                  # localhost / monadTestnet / monadMainnet
├── web/                       # Next.js 前端
│   ├── app/page.tsx                      # 竞拍场列表 + 创建竞拍
│   ├── app/auction/[id]/page.tsx         # 竞拍房间(黑金风格)
│   ├── lib/auction.ts                    # hash / 盐 / 精度计算(与合约字节级一致)
│   ├── lib/contract.ts                   # ABI、地址、常量、元组类型
│   ├── lib/items.ts                      # 待竞拍物品图鉴
│   └── components/                       # Navbar / Countdown / RulesCard / providers
├── seed-samples.cjs          # 注入 13 场样例竞拍
├── seed-items.cjs            # 追加 6 场「待竞拍」物品样例
├── drive-demo.cjs            # 将某场推进到丰富状态
└── docs/screenshots/         # README 用实拍图

⚙️ 核心业务规则

  • 密封出价hash = keccak256(abi.encodePacked(price, bidder, salt))
    • salt 为固定 18 字节bytes18),字母 / 数字 / 符号标点均可,多字节字符(中文 / emoji)会被前端拒绝。
  • 押金:报名需质押 100,000 MON(卖家创建竞拍时同样质押)。
  • 轮次:共 5 轮,人数不限。
    • 每轮:30s 提交 price hash → 30s 揭露原值;30s 未揭露直接进入比价,任何人可在 30s 后发起比价(compareRound)。
    • 出价约束:上一轮价格 ≤ 本轮出价 ≤ 最高价格 ≤ 100,000
  • 比价成交:第一名出价 ≥ 第二名 2 倍 → 直接拍下(若第 5 轮无 2 倍关系也直接成交)。
  • 结算:拍下后卖家揭露实际价格。
    • 第一名出价 < 实际价格 → 卖家支付差额;
    • 第一名出价 ≥ 实际价格 → 第一名支付差额给卖家。
  • 保证金退款(结算后自动退还):
    • 买家退款 = C + actualPrice − 2·winningBid
    • 卖家退款 = C + 2·winningBid − actualPrice
    • 卖家超时未揭露 → 保证金罚没给买家(finalizeNoReveal)。
  • 惰性推进:报名满 2 人记录 startAt = now + 30s,之后任何交互在超过该时间点后自动把阶段从 Open 推进到 Live,无需定时器。

🚀 本地运行(Hardhat 模拟链)

# 1. 启动本地节点(给 30 个账号各 1000 万 MON)
cd contracts
npx hardhat node

# 2. 新终端部署合约
cd contracts
npx hardhat run scripts/deploy.js --network localhost
# => 记下输出地址,如 0x5FbDB2315678afecb367f032d93F642f64180aa3

# 3. 前端指向合约
cd web
echo "NEXT_PUBLIC_CONTRACT_ADDRESS=0x5FbDB2315678afecb367f032d93F642f64180aa3" > .env.local

# 4. 构建并启动
npm install
npm run build && npm run start
# 浏览器打开 http://localhost:3000,MetaMask 切到 Localhost:8545 (chainId 31337)

注意:MetaMask 需要导入 hardhat 节点打印的私钥之一,并添加自定义网络 http://127.0.0.1:8545 / chainId 31337

填充演示数据(推荐)

启动空链后列表为空。运行以下脚本可批量注入样例竞拍,便于直接体验完整流程:

cd monad-auction
node seed-samples.cjs   # 注入 13 场样例(含已结算 / 进行中 / 报名中)
node seed-items.cjs     # 追加 6 场「待竞拍」物品样例(#14–#19)
node drive-demo.cjs     # 将某场推进到「Live 第1轮双方已揭露」的丰富状态
  • 三个脚本均使用「关闭自动挖矿 + 本地自增 nonce + 手动 evm_mine」的确定性时序,避免 nonce 错乱。
  • 演示账号(Hardhat 内置):#0 卖家 0xac09...ff80、#1 买家 0x59c6...690d、#3 买家 0x7099...

构建提示

next build 在结尾清理临时目录时中断,可改用独立构建目录绕过:

cd web
NEXT_DIST_DIR=.next-demo npx next build
NEXT_DIST_DIR=.next-demo npx next start -p 3000

🌐 部署到 Monad 测试网

# contracts/.env
PRIVATE_KEY=你的私钥
MONAD_TESTNET_RPC=https://testnet-rpc.monad.xyz

cd contracts
npx hardhat run scripts/deploy.js --network monadTestnet

# web/.env.local
NEXT_PUBLIC_CONTRACT_ADDRESS=<上一步输出的地址>

cd web
npm run build && npm run start

✅ 已通过验证

  • 合约 16 个 Hardhat 测试全部通过。
  • 前端 computeBidHash 与 Solidity abi.encodePacked(uint256, address, bytes18) 哈希字节级一致(20 组随机盐含 !@#$%^&*_-=+ 全部匹配)。
  • 精度解析 parseMonethers.parseEther 精确一致(BigInt 全程,无浮点误差)。
  • 本地节点 E2E 冒烟:创建 → 双人报名 → 惰性开局 → 5 轮完整出价 / 揭露 / 比价 → 卖家揭露 → 结算,退款余额分毫不差。

📄 许可证

MIT

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors