第四节DApp中的事件1.事件简介在传统的Web或App开发中,我们对“事件”的理解通常是用户操作触发的交互,例如点击按钮、输入文本、提交表单等。而在区块链和智能合约中,事件的概念有所不同。以太坊并没有内置“消息推送”机制,合约无法直接通知外部世界。为了让DApp或区块
在传统的 Web 或 App 开发中,我们对“事件”的理解通常是 用户操作触发的交互,例如点击按钮、输入文本、提交表单等。而在 区块链和智能合约 中,事件的概念有所不同。
以太坊并没有内置“消息推送”机制,合约无法直接通知外部世界。为了让 DApp 或区块链浏览器获知链上行为,事件(Event) 被设计为一种 轻量级日志记录方式。
特点:
📌 成本对比
- 事件(log)写入:约 2000 gas
- 存储一个状态变量:至少 20000 gas
因此在智能合约中,事件通常被用来记录重要信息,而不是直接修改合约存储。
在 Solidity 中,事件通过 event
关键字声明,并在合约运行时通过 emit
触发。
语法:
event EventName(type parameter1, type parameter2, ...);
你可以在合约里定义多个事件,常用于:
使用 emit
:
emit EventName(param1, param2, ...);
事件被触发后,会记录在交易日志(logs)中,DApp 可以通过 RPC 调用获取。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
contract MyToken is ERC721, Ownable {
uint256 private _nextTokenId = 0;
// 声明事件
event Minted(address minter, uint256 amount);
constructor() ERC721("MyToken", "MTK") Ownable(msg.sender) {}
function mint(uint256 quantity) public payable {
require(quantity == 1, "quantity must be 1");
require(msg.value == 0.01 ether, "must pay 0.01 ether");
uint256 tokenId = _nextTokenId++;
_mint(msg.sender, tokenId);
// 触发事件
emit Minted(msg.sender, quantity);
}
}
这里定义了 Minted
事件,在用户成功 mint NFT 后触发。这样前端 DApp 就能监听并更新界面。
在前端 DApp 中,我们无法直接从区块链获得“通知”,只能 通过 RPC 节点轮询或订阅合约日志 来获知事件发生。
借助 wagmi 这样的开发框架,我们可以用更简洁的方式来监听合约事件。
在 React + wagmi 项目中,可以使用 useWatchContractEvent
Hook:
import {
createConfig,
http,
useReadContract,
useWriteContract,
useWatchContractEvent,
} from "wagmi";
useWatchContractEvent({
address: "0xEcd0D12E21805803f70de03B72B1C162dB0898d9", // 合约地址
abi: [
{
anonymous: false,
inputs: [
{ indexed: false, internalType: "address", name: "minter", type: "address" },
{ indexed: false, internalType: "uint256", name: "amount", type: "uint256" },
],
name: "Minted",
type: "event",
},
],
eventName: "Minted",
onLogs(logs) {
console.log("Event logs:", logs);
message.success("New NFT minted!");
},
});
这样,当链上出现 Minted
事件时,DApp 就会收到回调。
监听事件在 DApp 中非常常见,典型的应用包括:
实时更新 UI
例如 NFT mint 成功后,前端界面自动显示最新的 Token ID。
交易状态反馈
用户发起交易 → 等待确认 → 收到事件 → 页面弹窗提示成功/失败。
构建通知系统
后端服务器也可以监听事件,并给用户推送通知(如邮件、Websocket、Telegram 机器人)。
索引与数据服务
像 The Graph 这类区块链索引服务,就是通过事件来同步链上数据。
不要把事件当成合约逻辑的一部分
合理使用 indexed
indexed
,最多 3 个。统一管理 ABI
兼顾前后端
event
定义,用 emit
触发。如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!