玩以太坊链上项目的必备技能(事件-Solidity之旅十二)

事件(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更高了。

扫描二维码关注公众号,回复: 14600693 查看本文章
// 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 。 同时也意味着对于匿名事件无法通过名字来过滤,仅能按合约地址过滤。 匿名事件的优势是他们部署和调用的成本更低。

由于交易日志只存储事件数据而不存储类型。你必须知道事件的类型,包括哪个参数被索引,以及该事件是否是匿名的,以便正确解释数据。 尤其是,有可能使用一个匿名事件来”伪造”另一个事件的签名。

猜你喜欢

转载自blog.csdn.net/coco2d_x2014/article/details/128365972