当前位置: 首页 > news >正文

Events

本节是《Solidity by Example》的中文翻译与深入讲解,专为零基础或刚接触区块链开发的小白朋友打造。我们将通过“示例 + 解说 + 提示”的方式,带你逐步理解每一段 Solidity 代码的实际用途与背后的逻辑。

Solidity 是以太坊等智能合约平台使用的主要编程语言,就像写网页要用 HTML 和 JavaScript,写智能合约就需要会 Solidity。

如果你从没写过区块链代码也没关系,只要你了解一点点编程概念,比如“变量”“函数”“条件判断”,我们就能从最简单的例子开始,一步步建立你的 Solidity 编程思维。

Events

事件
事件允许在以太坊区块链上记录日志。事件的一些用途包括:

  • 监听事件并更新用户界面
  • 作为一种廉价的存储方式

什么是 Solidity 事件?

在 Solidity 中,事件(Events)是智能合约与外部世界(如前端应用或链下服务)通信的机制,用于记录特定操作或状态变化到区块链的日志(logs)。

  • 比喻:事件像合约发出的广播信号,通知外界“某事发生了”,前端或链下服务可以监听这些信号并做出响应(如更新界面)。

  • 事件数据存储在区块链的日志中,成本远低于修改 storage 变量,是高效的链上记录方式。

  • 事件的用途

    • 监听事件并更新用户界面:
      • 前端(如 DApp)通过 Web3.js 或 Ethers.js 监听事件,实时更新页面显示(如显示转账记录)。
      • 比喻:像餐厅服务员喊“订单完成”,前台收到信号更新订单状态。
    • 廉价存储:
      • 事件数据存储在区块链的交易日志(logs)中,Gas 成本远低于 storage 变量(约 375 Gas 每 32 字节 vs. 20,000+ Gas 写 storage)。
      • 适合记录历史数据(如交易记录、状态变化),但不能直接在合约内读取。
      • 比喻:像在账本上记笔记,便宜但不能直接翻回去查(需链下工具)。
// SPDX-License-Identifier: MIT
// 使用 MIT 许可证,允许自由使用、修改和分发代码。pragma solidity ^0.8.26;
// 指定 Solidity 编译器版本,必须为 0.8.26 或更高(但低于 0.9.0)。contract Event {// 定义一个名为 Event 的智能合约,展示事件的定义和触发。// Event declaration// Up to 3 parameters can be indexed.// Indexed parameters help you filter the logs by the indexed parameter// 事件声明// 最多可以有 3 个参数被索引(indexed)。// 被索引的参数有助于通过该参数过滤日志。event Log(address indexed sender, string message);// 定义一个 AscII text// 定义一个事件 Log,包含两个参数:// - sender:address 类型,标记为 indexed(索引),可通过该参数高效过滤日志。// - message:string 类型,未索引,仅存储在日志数据中。// indexed 参数存储在日志的 topics 中,方便链下工具(如 Web3.js)按 sender 过滤事件。// 最多 3 个参数可标记为 indexed(Solidity 限制)。// 事件本身不消耗 storage,仅记录在交易日志中。event AnotherLog();// 定义一个无参数的事件 AnotherLog。// 无参数事件仅记录事件发生(无额外数据),适合简单通知场景。// 不带 indexed 参数,日志仅包含事件签名。function test() public {// 定义一个公共函数 test,用于触发事件。// public:可被外部和内部调用。// 不标记为 pure 或 view,因为触发事件会写入区块链日志,消耗 Gas。emit Log(msg.sender, "Hello World!");// 触发 Log 事件,记录:// - sender:调用者的地址(msg.sender,索引参数)。// - message:"Hello World!"(非索引参数)。// 事件数据写入交易日志,链下可监听。emit Log(msg.sender, "Hello EVM!");// 再次触发 Log 事件,记录:// - sender:调用者的地址(msg.sender,索引参数)。// - message:"Hello EVM!"(非索引参数)。emit AnotherLog();// 触发 AnotherLog 事件,无参数,仅记录事件发生。// 适合简单状态通知(如“某操作完成”)。}
}

Event 合约展示如何定义和触发事件:

  • 定义两个事件:Log(带参数,部分索引)和 AnotherLog(无参数)。
  • 使用 test 函数触发事件,记录调用者地址和消息到区块链日志。
  • 演示事件的基本用法和 indexed 参数的作用。

事件的本质

  • 事件是 Solidity 合约的日志记录机制,将数据写入区块链的交易日志,供链下工具(如前端、分析服务)读取和处理。
  • 比喻:
    • 事件如餐厅的公告板,记录“某人点了什么菜”(Log(sender, message)),前端可读取并显示给用户。
    • indexed 参数像公告板上的分类标签(如按用户地址排序),便于快速查找。
    • 事件不像 storage 变量(昂贵的账本),而是廉价的“便签”,记录后不可更改或直接查询。
  • 核心功能:
    • 记录操作:如记录转账、状态更新等,供链下工具(如 DApp)监听。
    • 高效存储:比修改 storage 变量便宜,适合保存历史记录。
    • 链下交互:通过 indexed 参数高效过滤日志(如按 sender 查找事件)。

代码功能

  • 事件 Log
    • 记录调用者地址(senderindexed)和消息(message)。
    • indexed 参数 sender 存储在日志的 topics 中,方便按地址过滤。
    • message 存储在日志的 data 字段,成本低但过滤效率较低。
  • 事件 AnotherLog
    • 无参数,仅记录事件发生,适合简单通知(如“操作完成”)。
  • 函数 test
    • 触发三次事件:两次 Log(带不同消息)一次 AnotherLog
    • 模拟合约操作(如用户交互)并记录到区块链日志。

事件的注意事项

  • 索引参数(indexed):

    • 最多 3 个 indexed 参数,存储在 topics,方便链下过滤(如按 sender 查找)。
    • 非索引参数存储在 data,成本低但过滤效率较低。
    • 选择合适的 indexed 参数(如地址、ID),避免浪费 topics。
  • Gas 成本:

    • 触发事件约 375 Gas 每 topic(事件签名 + 索引参数),data 每字节约 8 Gas。
    • storage 修改(20,000+ Gas)便宜,适合记录历史数据。
    • 复杂参数(如长字符串)增加 Gas,尽量精简 data 字段。
  • 安全性:

    • 事件仅记录日志,不影响合约逻辑,需确保触发条件正确。

    • 结合错误处理(如require、revert)验证输入:

      function deposit() public payable {require(msg.value > 0, "No value sent");emit Deposit(msg.sender, msg.value);
      }
      
    • 使用修饰器(如onlyOwner)限制敏感事件触发(参考历史对话):

      modifier onlyOwner() {require(msg.sender == owner, "Not owner");_;
      }
      function logAdminAction() public onlyOwner {emit Log(msg.sender, "Admin action");
      }
      
  • 链下交互:

    • 事件不可在合约内直接读取,需链下工具(如 Web3.js、Ethers.js)处理。
    • 确保事件参数清晰(如 indexed sender 便于过滤),便于 DApp 使用。
http://www.lryc.cn/news/595917.html

相关文章:

  • Linux部署.net Core 环境
  • 虚幻 5 与 3D 软件的协作:实时渲染,所见所得
  • linux-日志服务
  • 同步本地文件到服务器上的Docker容器
  • 跨维智能:全新一代人形机器人 DexForce W1 Pro
  • 大模型后训练——DPO实践
  • Mosaic数据增强介绍
  • 使用ubuntu:20.04和ubuntu:jammy构建secretflow环境
  • android模拟器手机打开本地网页
  • Tailwind CSS快速上手 Tailwind CSS的安装、配置、使用
  • J2EE模式---拦截过滤器模式
  • Vite:下一代前端构建工具的革命
  • C语言---VSCODE的C语言环境搭建
  • RISC-V基金会Datacenter SIG月会圆满举办,探讨RAS、PMU性能分析实践和经验
  • vs2017 c++ 使用sqlite3数据库
  • 末日期权的双买和单买策略区别是什么?
  • 双向链表详解及实现
  • C++_Hello算法_队列
  • 基于Java+MySQL实现(Web)文件共享管理系统(仿照百度文库)
  • 188粉福
  • Spring快速整合Mybatis
  • 技术与情感交织的一生 (十)
  • nodejs:告别全局安装,npx 命令详解及其与 npm 的区别
  • 从零开始学CTF(第二十五期)
  • Gitlab-CI实现组件自动推送
  • n8n - 为技术团队提供安全的自动化工作流
  • 基于Kubernetes的微服务CI/CD:Jenkins Pipeline全流程实践
  • 知识库搭建之Meilisearch‘s 搜索引擎 测评-东方仙盟测评师
  • STL学习(一、string容器)
  • 暑假算法训练.6