事件是合约和外部世界之间的通信机制。
它允许合约发送信息给外部世界,并允许外部世界监听和响应这些信息。
事件可以在合约内部定义,然后在合约内部触发。
外部世界可以监听这些事件并做出相应的反应。
事件定义如下:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;
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();
}
}
event
关键字用于定义一个事件。Log
是事件的名称。address
和string
是事件参数的类型。indexed
关键字用于对事件参数创建索引,从而使查询更高效。
现在,我们来看看如何监听事件并做出响应。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.3;
contract Event {
event Log(address indexed sender, string message);
function test() public {
emit Log(msg.sender, "Hello World!");
}
}
contract HelloWorld {
address private _eventContractAddress;
constructor(address eventContractAddress) {
_eventContractAddress = eventContractAddress;
}
function listenEvent() public view returns (string memory) {
Event eventContract = Event(_eventContractAddress);
return getMessage(eventContract);
}
function getMessage(Event eventContract) private view returns (string memory) {
uint256 totalEvents = eventContract.getEventCount();
(address sender, string memory message) = eventContract.getEventData(totalEvents - 1);
return message;
}
}
- 这个例子中有两个合约,
Event
和HelloWorld
。Event
合约定义了事件,并在test
函数中触发该事件。 HelloWorld
合约通过事件的地址访问事件合约。然后它调用getMessage
方法来检索最新的事件数据。getEventData
函数用于检索事件数据。
- 事件是异步的,因此无法从合约本身读取事件数据。必须使用外部合约来检索事件数据。
- 目前只能检索最近一次事件数据。