在本章中,我们将探索 Cairo 中的事件(events)。在释放时,事件会将传递给它们的参数存储在 Starknet 交易日志中。
事件
类似于 Solidity,Cairo 中的事件是存储在 Starknet 上的交易日志。事件在函数调用时被释放,并可以被外部的链下应用访问。
以下是Starknet 的事件例子。这是ERC20合约中的一个 Transfer
事件,它包含三个参数:'from','to',和 'value'。

事件具有以下几个特点:
- 将数据存储在事件中比存储在存储变量中更具成本效益。
- 事件不能直接从合约内部读取。
- 诸如 starknet.js 的应用程序可以通过 RPC 接口订阅这些事件,并在前端触发响应。
为了更好地说明 Cairo 中的事件,我们扩展了上一章中的 Owner
合约示例。具体来说,我们添加了一个 ChangeOwner
事件,每次更改所有者时都会释放这个事件。
定义事件
在 Cairo 中,事件是通过事件枚举。你需要使用#[event]
和#[derive(Drop, starknet::Event)]
属性,每个事件变体成员必须是一个与变体同名的结构体。然后,你需要定义事件结构体,它也需要使用#[derive(Drop, starknet::Event)]
属性,并将你想要记录的参数添加为成员。在下面的例子中,我们定义了一个 ChangeOwner
事件,它有两个参数:旧所有者和新所有者的地址。
释放事件
要释放事件,你需要使用self.emit()
方法,并把要记录的数据作为参数。在下面的例子中,ChangeOwner
事件在 change_owner()
函数中的 owner
更改后释放。
读取释放的事件
可以使用 Starknet.js 库读取释放的事件,这是一个用于 Starknet 的 JavaScript 库,类似于以太坊的 Ethers.js 。有关更多信息,请参阅 Starknet.js 文档。
总结
在本章中,我们介绍了 Cairo 中的事件,它们提供了一种高效的存储数据和跟踪合约中状态变化的方法。它们可以用于开发响应式的去中心化应用。