事件(Events)
Solidity 中的事件(Events)
与任何一种编程语言中事件(Events)
一样。
一个事件(Events)
是一个合约可继承的成员,它在触发(emit)
时存储在交易日志中传递的参数。
在EVM
的日志设施下,事件(Events)
被用来通知调用应用程序关于合约的当前状态。事件(Events)
通知应用程序关于对合约和应用程序所做的改变,可以用来执行依赖逻辑。
如果外部实体需要该日志实际上存在于区块链中的证明,可以请求日志的Merkle证明. 但需要留意的是,由于合约中仅能访问最近的 256 个区块哈希,所以还需要提供区块头信息。
对日志的证明是可能的,如果一个外部实体提供了一个带有这种证明的合约,它可以检查日志是否真实存在于区块链中。
最多三个参数可以接收 indexed
属性(它是一个特殊的名为:ref:”主题” <abi_events> 的数据结构, 而不作为日志的数据部分)。 主题仅有 32 字节, 因此如果 引用类型]标记为索引项,则它们的 keccak-256 哈希值会被作为 主题topic 保存。
所有非索引 indexed
参数是 ABI-encoded 都将存储在日志的数据部分中。
主题topic 让我们可以可以搜索事件,比如在为某些事件过滤一些区块,还可以按发起事件的合同地址来过滤事件。
事件声明
事件(Events)
在合约中被定义为全局的,并在其函数中被调用。事件(Events)
是通过使用events
关键字来声明的,后面是一个标识符和参数列表,并以分号结尾。参数值用于记录信息或执行条件逻辑。它的信息和值被保存为块内事务的一部分。不需要提供变量,只有数据类型就足够了。一个事件(Events)
可以通过使用其名称和传递所需的参数从任何函数中调用。
event <eventName>(parameters) ;
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;
contract eventExample {
uint256 public value = 0;
//声明一个时间 用于记录 调用者的地址
event Increment(address owner);
function getValue(uint _a, uint _b) public {
//触发 事件
emit Increment(msg.sender);
value = _a + _b;
}
}
添加了索引的事件,虽然方便了查找,但 gas fee
更高了。
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;
contract eventExample {
//声明一个时间 用于记录 调用者的地址
event NewTrade(
uint256 indexed date,
address from,
address indexed to,
uint256 indexed amount
);
function trade(address to, uint256 amount) external {
emit NewTrade(block.timestamp, msg.sender, to,amount);
}
}
使用javascript
进行调用:
var abi = /* abi 由编译器产生 */;
var eventExampleABI = web3.eth.contract(abi);
var eventExample = eventExampleABI.at("0x1234...xlb67" /* 地址 */);
var tradeEvent = eventExample.NewTrade();
// 监听变化
tradeEvent.watch(function(error, result) {
// 结果包含 非索引参数 以及 主题 topic
if (!error)
console.log(result);
});
// 或者通过传入回调函数,立即开始听监
var tradeEvent = eventExample.NewTrade(function(error, result) {
if (!error)
console.log(result);
});
除非你用 anonymous
声明事件(Events)
,否则事件(Events)
签名的哈希值是一个 主题topic 。 同时也意味着对于匿名事件无法通过名字来过滤,仅能按合约地址过滤。 匿名事件的优势是他们部署和调用的成本更低。
由于交易日志只存储事件数据而不存储类型。你必须知道事件的类型,包括哪个参数被索引,以及该事件是否是匿名的,以便正确解释数据。 尤其是,有可能使用一个匿名事件来”伪造”另一个事件的签名。