事件
- 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 用于过滤事件,而不需要知道其具体参数值。