Solidity极简入门: 12. 事件

我最近在重新学solidity,巩固一下细节,也写一个“Solidity极简入门”,供小白们使用(编程大佬可以另找教程),每周更新1-3讲。

欢迎关注我的推特:@0xAA_Science

欢迎加入WTF科学家社区:discord

所有代码开源在github(64个star开微信交流群,已开填表加入;128个star录教学视频): github.com/AmazingAng/WTFSolidity


这一讲,我们用转账ERC20代币为例来介绍solidity中的事件(event)。

事件

Solidity中的事件(event)是EVM上日志的抽象,它具有两个特点:

  • 响应:应用程序(ether.js)可以通过RPC接口订阅和监听这些事件,并在前端做响应。
  • 经济:事件是EVM上比较经济的存储数据的方式,每个大概消耗2,000-5,000 gas不等。相比之下,存储一个新的变量至少需要20,000 gas

规则

事件的声明由event关键字开头,然后跟事件名称,括号里面写好事件需要记录的变量类型和变量名。以ERC20代币合约的Transfer事件为例:

event Transfer(address indexed from, address indexed to, uint256 value);

我们可以看到,Transfer事件共记录了3个变量fromtovalue,分别对应代币的转账地址,接收地址和转账数量。同时fromto前面带着indexed关键字,表示很重要,程序可以轻松的筛选出特定转账地址和接收地址的转账事件。每个事件最多有3个带indexed的变量。

我们可以在函数里释放事件。在下面的例子中,每次用_transfer()函数进行转账操作的时候,都会释放Transfer事件,并记录相应的变量。

// 定义_transfer函数,执行转账逻辑
function _transfer(
    address from,
    address to,
    uint256 amount
) external {

    _balances[from] = 10000000; // 给转账地址一些初始代币

    _balances[from] -=  amount; // from地址减去转账数量
    _balances[to] += amount; // to地址加上转账数量

    // 释放事件
    emit Transfer(from, to, amount);
}

在etherscan上查询事件

我们尝试用_transfer()函数在Rinkeby测试网络上转账100代币,可以在etherscan上查询到相应的tx网址

点击Logs按钮,就能看到事件明细:

Event明细
Event明细

Topics里面有三个元素,[0]是这个事件的哈希,[1][2]是我们定义的两个indexed变量的信息,即转账的转出地址和接收地址。Data里面是剩下的不带indexed的变量,也就是转账数量。

总结

这一讲,我们介绍了如何使用和查询solidity中的事件。很多链上分析工具包括NansenDune Analysis都是基于事件工作的。

Subscribe to 0xAA
Receive the latest updates directly to your inbox.
Mint this entry as an NFT to add it to your collection.
Verification
This entry has been permanently stored onchain and signed by its creator.