Skip to main content

事件

  • Solidity 事件是 EVM 的日志功能之上的抽象。 应用程序可以通过以太坊客户端的 RPC 接口订阅和监听这些事件
  • 事件在合约中可被继承
  • 日志和事件在合约内不可直接被访问
  • 事件可以添加索引,最多三个参数可以接收 indexed 属性
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.3;

contract Event {
event Log(string message, uint val);
event IndexedLog(address indexed sender, uint val);
event Message(address indexed from, address indexed to, string message);

function example() external {
emit Log("foo",1234);
emit IndexedLog(msg.sender, 789);
}

function sendMessage(address _to,string calldata _message) external {
emit Message(msg.sender,_to, _message);
}
}

Event 的 topic

在 Solidity 中,event 的 topic 是通过对 event 签名进行 Keccak-256 哈希计算得到的。

一个 event 的签名是由 event 名称和参数类型构成,格式如下:

eventName(param1Type, param2Type, ...)

例如一个 event 的定义是:

event Transfer(address indexed from, address indexed to, uint value)

则该 event 的签名是:

Transfer(address,address,uint256)

对这个签名计算 Keccak-256 哈希,结果就是该 event 的 topic。

代码实现如下:

bytes32 topic = keccak256("Transfer(address,address,uint256)");

在响应 event 时,Solidity 会将参数值放入数据字段 data,并以 topic 的哈希作为索引,以便过滤事件。

所以在智能合约中,我们只需要根据 event 的签名就可以预先计算出其 topic, later 用于过滤事件,而不需要知道其具体参数值。