下面是一个完整的 Ethers.js + Express + Vue2 + MySQL 实现方案,用于:
💡每天凌晨 2 点监听某合约地址的 Transfer 事件,写入 MySQL 数据库,并展示每日 NFT 交易量图表(Vue2 + ECharts)
✅ 后端部分(Express + Ethers.js + MySQL)
📁 项目结构(后端部分):
backend/
├── abi/NFT_ABI.json
├── db.js
├── syncTransfers.js
├── api.js
└── server.js
📌 1. db.js
(MySQL 连接池)
const mysql = require('mysql2/promise');
const pool = mysql.createPool({
host: 'localhost',
user: 'root',
password: 'yourpassword',
database: 'nft_data',
});
module.exports = pool;
📌 2. syncTransfers.js
(同步 NFT Transfer 数据)
const { ethers } = require('ethers');
const pool = require('./db');
const abi = require('./abi/NFT_ABI.json');
const provider = new ethers.JsonRpcProvider('https://sepolia.infura.io/v3/YOUR_INFURA_KEY');
const contract = new ethers.Contract('0xYourContractAddress', abi, provider);
async function syncTransfers() {
const latestBlock = await provider.getBlockNumber();
const fromBlock = latestBlock - 5000;
const toBlock = latestBlock;
const events = await contract.queryFilter('Transfer', fromBlock, toBlock);
for (const event of events) {
const { transactionHash, blockNumber, args } = event;
const { from, to, tokenId } = args;
const block = await provider.getBlock(blockNumber);
const timestamp = new Date(block.timestamp * 1000);
await pool.execute(`
INSERT IGNORE INTO nft_transfers (tx_hash, from_address, to_address, token_id, block_number, timestamp)
VALUES (?, ?, ?, ?, ?, ?)
`, [transactionHash, from, to, tokenId.toString(), blockNumber, timestamp]);
}
console.log(`✅ Synced ${events.length} transfers`);
}
module.exports = syncTransfers;
📌 3. api.js
(提供每日统计 API)
const express = require('express');
const pool = require('./db');
const router = express.Router();
router.get('/daily-stats', async (req, res) => {
const [rows] = await pool.execute(`
SELECT DATE(timestamp) as day, COUNT(*) as count
FROM nft_transfers
GROUP BY day ORDER BY day DESC LIMIT 7
`);
res.json(rows);
});
module.exports = router;
📌 4. server.js
(Express + 定时任务)
const express = require('express');
const cron = require('node-cron');
const syncTransfers = require('./syncTransfers');
const api = require('./api');
const app = express();
app.use('/api', api);
// 定时任务:每天凌晨 2 点执行
cron.schedule('0 2 * * *', () => {
console.log('⏰ Running daily syncTransfers job...');
syncTransfers();
});
app.listen(3000, () => {
console.log('🚀 Server running on http://localhost:3000');
});
📌 5. SQL 建表语句
CREATE TABLE nft_transfers (
id INT AUTO_INCREMENT PRIMARY KEY,
tx_hash VARCHAR(66),
from_address VARCHAR(42),
to_address VARCHAR(42),
token_id VARCHAR(100),
block_number INT,
timestamp DATETIME,
UNIQUE(tx_hash)
);
✅ 前端部分(Vue2 + Axios + ECharts)
📁 frontend/src/components/Chart.vue
<template>
<div>
<h2>每日 NFT 交易量</h2>
<div id="chart" style="height: 400px"></div>
</div>
</template>
<script>
import axios from 'axios';
import echarts from 'echarts';
export default {
mounted() {
axios.get('/api/daily-stats').then(res => {
const days = res.data.map(r => r.day);
const counts = res.data.map(r => r.count);
const chart = echarts.init(document.getElementById('chart'));
chart.setOption({
title: { text: '每日交易量' },
tooltip: {},
xAxis: { type: 'category', data: days },
yAxis: { type: 'value' },
series: [{ type: 'line', data: counts }]
});
});
}
};
</script>
✅ 最后提示
🔧 确保将 Infura Key、合约地址、ABI 替换为你自己的
✅
Transfer
事件仅适用于符合 ERC721/1155 标准的 NFT 合约📦 启动命令如下:
# 安装依赖
npm install express mysql2 ethers node-cron axios echarts
# 启动后端
node server.js
# 启动前端(Vue2)
npm run serve
如果你还想加:
统计活跃地址数
展示 NFT TokenId 的交易趋势
接入钱包连接
用 NestJS 替换 Express
可以继续说,我可以帮你逐步拓展。