0%

solidity | 事件 event 与 logs

事件可以让外部获取智能合约的状态变化。

事件是以太坊的日志接口,可索引。

使用事件

1
2
3
4
5
//声明事件,可继承
event EventName(uint param);

// 发出事件
emit EventName(10);
1
2
3
4
5
6
7
8
9
10
pragma solidity ^0.4.18;

contract Test{

event Despoit(address _from,uint _value);

function despoit() public payable{
emit Despoit(msg.sender,msg.value);
}
}

使用案例

bsc 测试网上部署合约

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
pragma solidity ^0.8.0;

contract ERC20{

event EventName1(uint param1,uint parma2,uint param3);
event EventName2(uint indexed param1,uint indexed parma2,uint param3);
event EventName3(uint indexed param1,uint indexed parma2,string indexed param3);
event EventName4(uint indexed param1,uint indexed parma2,string param3);
event EventName5(uint indexed param1,uint indexed parma2,uint indexed param3);
event EventName6(uint indexed param1,uint indexed parma2,uint indexed param3,uint param4);

function test() public{
emit EventName1(1,2,3);
emit EventName2(1,2,3);
emit EventName3(1,2,"i am some tert iuj jkjis jduh jhajshd jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjji am some tert iuj jkjis jduh jhajshd jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjji am some tert iuj jkjis jduh jhajshd jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjji am some tert iuj jkjis jduh jhajshd jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjji am some tert iuj jkjis jduh jhajshd jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjji am some tert iuj jkjis jduh jhajshd jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjji am some tert iuj jkjis jduh jhajshd jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjji am some tert iuj jkjis jduh jhajshd jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjji am some tert iuj jkjis jduh jhajshd jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjji am some tert iuj jkjis jduh jhajshd jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjji am some tert iuj jkjis jduh jhajshd jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjji am some tert iuj jkjis jduh jhajshd jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjji am some tert iuj jkjis jduh jhajshd jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjji am some tert iuj jkjis jduh jhajshd jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjji am some tert iuj jkjis jduh jhajshd jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjji am some tert iuj jkjis jduh jhajshd jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjji am some tert iuj jkjis jduh jhajshd jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjji am some tert iuj jkjis jduh jhajshd jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjji am some tert iuj jkjis jduh jhajshd jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjji am some tert iuj jkjis jduh jhajshd jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjji am some tert iuj jkjis jduh jhajshd jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjji am some tert iuj jkjis jduh jhajshd jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjji am some tert iuj jkjis jduh jhajshd jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjji am some tert iuj jkjis jduh jhajshd jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjji am some tert iuj jkjis jduh jhajshd jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjji am some tert iuj jkjis jduh jhajshd jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjji am some tert iuj jkjis jduh jhajshd jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjji am some tert iuj jkjis jduh jhajshd jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjji am some tert iuj jkjis jduh jhajshd jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjji am some tert iuj jkjis jduh jhajshd jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj");
emit EventName4(1,2,"i am some tert iuj jkjis jduh jhajshd jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjji am some tert iuj jkjis jduh jhajshd jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjji am some tert iuj jkjis jduh jhajshd jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjji am some tert iuj jkjis jduh jhajshd jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjji am some tert iuj jkjis jduh jhajshd jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjji am some tert iuj jkjis jduh jhajshd jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjji am some tert iuj jkjis jduh jhajshd jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjji am some tert iuj jkjis jduh jhajshd jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjji am some tert iuj jkjis jduh jhajshd jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjji am some tert iuj jkjis jduh jhajshd jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjji am some tert iuj jkjis jduh jhajshd jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjji am some tert iuj jkjis jduh jhajshd jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjji am some tert iuj jkjis jduh jhajshd jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjji am some tert iuj jkjis jduh jhajshd jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjji am some tert iuj jkjis jduh jhajshd jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjji am some tert iuj jkjis jduh jhajshd jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjji am some tert iuj jkjis jduh jhajshd jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjji am some tert iuj jkjis jduh jhajshd jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjji am some tert iuj jkjis jduh jhajshd jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjji am some tert iuj jkjis jduh jhajshd jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjji am some tert iuj jkjis jduh jhajshd jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjji am some tert iuj jkjis jduh jhajshd jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjji am some tert iuj jkjis jduh jhajshd jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjji am some tert iuj jkjis jduh jhajshd jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjji am some tert iuj jkjis jduh jhajshd jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjji am some tert iuj jkjis jduh jhajshd jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjji am some tert iuj jkjis jduh jhajshd jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjji am some tert iuj jkjis jduh jhajshd jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjji am some tert iuj jkjis jduh jhajshd jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjji am some tert iuj jkjis jduh jhajshd jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj");
emit EventName5(1,2,3);
emit EventName6(1,2,3,4);
}

}

其地址为

使用 test 方法后,相关的事件如下

这里进行剖析

logs 一共有几个属性

  • Topics
    • 0
    • 1
    • 2
    • 3
  • Data

主题 Topics

日志的第一部分是主题数组,用于描述事件,长度不能超过4。它的第一个元素是事件的签名(哈希)。对于上面的各个事件,它的签名就是:

keccak256("EventName1(uint256,uint256,uint256)") -> 33d95c16bf92dbaf1521e0b456411aca1d7a77c79d7d3f9fe1ec891ebb599916
keccak256("EventName2(uint256,uint256,uint256)") -> 243610548e8736f067121509e22a1b7e1930be3f216e0d24b67e84fb69f59c8c
...

这些都能和浏览器数据对的上。

所以,topics 中的 0 是无论如何都存在的。

主题还可以包含至多 3indexed 参数。indexed 标记的参数可以理解为检索事件的索引“键”,方便之后搜索。每个 indexed 参数的大小为固定的 256 比特,如果参数太大了(比如字符串),就会自动计算哈希存储在主题中。

看上面的事件

1
2
3
event EventName1(uint param1,uint parma2,uint param3);
event EventName2(uint indexed param1,uint indexed parma2,uint param3);
event EventName3(uint indexed param1,uint indexed parma2,string indexed param3);

只有有 indexed 的才会有 topics 索引。

数据 Data

事件中不带 indexed 的参数会被存储在 data 部分中,可以理解为事件的“值”。data 部分的变量不能被直接检索,但可以存储任意大小的数据。因此一般 data 部分可以用来存储复杂的数据结构,例如数组和字符串等等,因为这些数据超过了 256 比特,即使存储在事件的 topic 部分中,也是以哈希的方式存储。另外,data 部分的变量在存储上消耗的 gas 相比于 topic 更少。

但是,上面的第三个事件就和区块链浏览器对不上,个人感觉很有可能是 bsc 阉割了部分服务,不过,这个倒不是很重要了。

请我喝杯咖啡吧~