17.Events
事件¶
Events allow logging to the Ethereum blockchain. Some use cases for events are:
- Listening for events and updating user interface
- A cheap form of storage
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.1;
contract Event {
// Event declaration
// Up to 3 parameters can be indexed.
// Indexed parameters helps you filter the logs by the indexed parameter
event Log(address indexed sender, string message);
event AnotherLog();
function test() public {
emit Log(msg.sender, "Hello World!");
emit Log(msg.sender, "Hello EVM!");
emit AnotherLog();
}
}
事件是能方便地调用以太坊虚拟机日志功能的接口。应用程序可以通过以太坊客户端的 RPC 接口订阅和监听这些事件。
重点:记录区块链的日志,可以使用状态变量,也可以使用事件 Event,但 Event 使用的 gas 费比状态变量低。
原则:改变状态变量时,一定要触发事件。
Event 语法¶
事件的定义:使用 event 关键字来定义一个事件 Event,语法如下:
event EventName(<parameter list>);
事件的触发:只能使用 emit 关键字来触发事件 Event,语法如下:
emit EventName(<parameter list>);
四种事件定义方式¶
- 不带参数的 event
- 带参数的 event
- 带参数名的 event
- 带 indexed 参数名的 event
- 这种事件也被称为索引事件
- 语法:
event EventName(TypeName indexed varibleName....); - 事件中 indexed 标记过的参数,可以在链外进行搜索查询。
- 一个事件中 indexed 标记过的参数最多有 3 个。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;
contract Event {
// 普通 event
event Log1(address, string);
// 带名字的 event
event Log2(address ads, string msg);
// 带 indexed 的event
event Log3(address indexed ads, string msg);
// indexed 在一个事件内使用次数不能超过3次
event Transfer(
address indexed from,
address indexed to,
uint256 indexed amount
);
function log1() external {
emit Log1(msg.sender, "Log111");
}
function log2() external {
emit Log2(msg.sender, "Log222");
}
function log3() external {
emit Log3(msg.sender, "Log333");
}
function transfer(address _to, uint256 amount) external {
emit Transfer(msg.sender, _to, amount);
}
}
不带参数的 event¶
[
{
"from": "0x7874d94b8f9E2a28FCceCE404666C984f33a82b8",
"topic": "0x1732d0c17008d342618e7f03069177d8d39391d79811bb4e706d7c6c84108c0f",
"event": "Log1",
"args": {}
}
]
带参数的 event¶
[
{
"from": "0x7874d94b8f9E2a28FCceCE404666C984f33a82b8",
"topic": "0x54010eb0426bdddd13273086604fca7ba750a84093c6839732d954056646e81b",
"event": "Log2",
"args": {
"0": "0x5B38Da6a701c568545dCfcB03FcB875f56beddC4",
"1": "Log222"
}
}
]
带参数名的 event¶
[
{
"from": "0x7874d94b8f9E2a28FCceCE404666C984f33a82b8",
"topic": "0x940879bf2d29cdfe8084f2f033d2168f5859a6e10530b61fb84dc1c5ddc9ca40",
"event": "Log3",
"args": {
"0": "0x5B38Da6a701c568545dCfcB03FcB875f56beddC4",
"1": "Log333",
"ads": "0x5B38Da6a701c568545dCfcB03FcB875f56beddC4",
"msg": "Log333"
}
}
]
带 indexed 参数名的 event¶
[
{
"from": "0xfB72aAdB17a855D27A68B565ee0a84CB30A387e4",
"topic": "0xf485c071883274befba21423da7f60203f9df753bf614bca26c4763ed4b240fb",
"event": "Log4",
"args": {
"0": "0x5B38Da6a701c568545dCfcB03FcB875f56beddC4",
"1": "Log444",
"ads": "0x5B38Da6a701c568545dCfcB03FcB875f56beddC4",
"msg": "Log444"
}
}
]
[
{
"from": "0xfB72aAdB17a855D27A68B565ee0a84CB30A387e4",
"topic": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"event": "Transfer",
"args": {
"0": "0x5B38Da6a701c568545dCfcB03FcB875f56beddC4",
"1": "0x5B38Da6a701c568545dCfcB03FcB875f56beddC4",
"2": "1",
"from": "0x5B38Da6a701c568545dCfcB03FcB875f56beddC4",
"to": "0x5B38Da6a701c568545dCfcB03FcB875f56beddC4",
"amount": "1"
}
}
]
¶
案例¶
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.1;
contract Event {
// 事件是合约与外部世界通信的一种方式,通过发出日志条目来与外部应用程序进行通信。
// 一个event中indexed最多标注三个
// indexed关键字表示sender参数将包含在日志条目的索引部分中,这使得更容易搜索特定事件。
event Log(string message, uint256 val);
// 两个参数:一个名为sender的索引地址和一个名为val的无符号整数。
event IndexedLog(address indexed sender, uint256 val);
/**
函数发出了两个事件:
Log事件,消息为“foo”,值为1234,
IndexedLog事件,带有发送方地址和值789。
**/
function example() external {
emit Log("foo", 1234);
emit IndexedLog(msg.sender, 789);
}
event Message(address indexed _from, address indexed _to, string message);
// 函数发出了一个Message事件,带有发送方地址、接收方地址和消息字符串。
function sendMessage(address _to, string calldata message) external {
emit Message(msg.sender, _to, message);
}
}