本文以以太坊投票合约为例,详解如何用 ethers.js + MetaMask 快速开发前端页面,并补充后端读取思路,帮助开发者建立 Dapp 完整认知,涵盖钱包连接、ABI 调用、事件监听、数据缓存与 The Graph 等高频 区块链 开发知识点。
一、为什么需要 Dapp?
上一节我们用 Etherscan 人为调用合约,虽然可行,却让非技术用户望而却步。把「调用 JSON-RPC」过程封装进「网页按钮」里,正是 去中心化应用(Dapp) 的本质:
- 普通用户只看页面,无感知地与 智能合约 互动;
- 开发者负责把「链上逻辑」翻译为用户可点击的操作界面。
二、Dapp 的三种典型架构
- 纯前端 Dapp
浏览器 + 钱包即可完成合约读取、写入,无需后端。 - 前端 + 后端(Dapp Server)
当用户未安装钱包或网络不匹配时,后端提供只读数据。 - 前端 + The Graph
省去自建后端,按索引写 GraphQL 查询即可。
无论你选哪种方案,核心 核心关键词:Web3 前端、智能合约、区块链、以太坊、ethers.js、MetaMask.
三、10 分钟搭建最小可运行前端 Dapp
以下流程全部基于 ethers.js,本地仅开一个静态 HTML 即可体验。
步骤 1 引入依赖
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/ethers.umd.min.js"></script>步骤 2 获取钱包 Provider
function getWeb3Provider() {
if (!window.ethereum) {
console.error('未检测到钱包插件');
return null;
}
return new ethers.providers.Web3Provider(window.ethereum, 'any');
}步骤 3 连接 MetaMask
document.getElementById('connect-btn').addEventListener('click', async () => {
const provider = getWeb3Provider();
if (!provider) return;
await window.ethereum.request({ method: 'eth_requestAccounts' });
console.log('钱包连接成功');
});步骤 4 读取 & 写入合约
把 Remix 编译出的
Vote.json中 ABI 复制出来,存为VOTE_ABI常量:const VOTE_ABI = [...]; const VOTE_ADDR = '0x5b2a057e1db47463695b4629114cbdae99235a46'; // 你的部署地址调用投票
vote()方法:export async function vote(proposal) { const signer = getWeb3Provider().getSigner(); const contract = new ethers.Contract(VOTE_ADDR, VOTE_ABI, signer); const tx = await contract.vote(proposal); await tx.wait(1); // 1 个区块确认 }
👉 不想自己跑节点?点我教你 5 分钟用公共 RPC 部署后端!
四、为什么还少不了后端
当用户浏览器未安装钱包,前端无法直接读取 智能合约 数据。此时需要一台 只读后端(Dapp Server):
- 不存私钥,仅拉取链上事件或状态;
- 缓存结果,供前端快速渲染;
- 监听事件而非轮询,降低资源消耗。
后端三大任务
连接节点
- 公共节点:Infura / Alchemy / Cloudflare;
- 自建节点:Geth / OpenEthereum。
监听日志
eventcontract.on("VoteCast", (voter, proposal, value) => { // 移入本地数据库或缓存 });数据聚合与 API 化
- 统计票型实时走势;
- 接口
/votes/:proposalId向前端提供聚合结果。
五、用 The Graph 消除后端烦恼
The Graph 把「索引」外包:
- 你写 Subgraph定义 (
schema.graphql、mapping.ts); - Graph Network 监听事件 → 更新索引;
- 前端用 GraphQL 直接查询。
VoteDapp 替换示意图:
- 前端 ←→ The Graph(GraphQL)
- 前端 ←→ 合约(读写)
无需自建服务器,时间成本降至 数小时。
六、FAQ:10 个高频疑问一次解答
Q1:没有 MetaMask 的浏览器怎么办?
A:引导用户安装或切换到兼容钱包,如 Rabby / Rabby Mobile;纯 H5 场景可用 WalletConnect 。
Q2:ethers.js 一定要 5.x 版本吗?
A:目前 6.x 处于 Beta,关键 API 变动大,生产代码仍以 5.x 为准。
Q3:ABI 与地址泄露会不会有风险?
A:ABI/地址本来就是公开信息,不影响安全性;真正需要保密的是私钥。
Q4:后端监听失败怎么办?
A:常见原因:
- 事件签名写错;
- 节点不支持
eth_getLogs某些区间。改为分页查询即可。
Q5:如何判断前端和合约网络一致?
A:连接钱包后读取 window.ethereum.request({ method: 'eth_chainId' }),与期望 chainId 比对即可。
Q6:钱包每次都要重新授权吗?
A:eth_requestAccounts 授权一次即可缓存,除非用户清除浏览数据。
Q7:can I use React?
A:可无缝接入 React、Vue 或 Svelte,核心逻辑(getWeb3Provider)不变。
Q8:The Graph 提款周期多久?
A:主网 Indexer 通常 5-20 分钟,测试网更快。
Q9:部署主网还是侧链?
A:投票类低价值场景,推荐 Polygon 或 Arbitrum;大额资产需主网。
Q10:测试币哪里领?
A:分别去官方水龙头(Goerli/ Sepolia),或通过桥接 Twitter 验证平台。
七、实战到盈利:开发→运营→迭代
- 阶段一 MVP:先跑通 Vote 逻辑,功能单一,关键验证交互流程。
- 阶段ニ 数据可视化:接入后端/Graph,增加投票进度条 + 热搜榜,提升分享率。
- 阶段三 商业化:扩展为 Token 治理接口,后续可加投票激励模型,进入 DAO 赛道。
无论处在哪一阶段,务必确保 智能合约逻辑简洁 + 事件日志完备 + 后端缓存友好,才能撑起前端体验与用户增长。
小结
- Web3 前端 负责用户交互;
- 智能合约 负责核心业务逻辑;
- 后端或 Graph 负责链下聚合;
三者协作,才能构建真正可用的 Dapp。
下一步,不妨用今天学到的 vote 合约模板,加上后端缓存或 The Graph,上线一个真正可运行的「谁能赢」投票小游戏。祝编码愉快!