Sway 如何用 [event] 与 [indexed] 定义可过滤的合约事件?
Sway 如何用 #[event] 与 #[indexed] 定义可过滤的合约事件【免费下载链接】sway Empowering everyone to build reliable and efficient smart contracts.项目地址: https://gitcode.com/GitHub_Trending/sw/sway写 Fuel 合约时你经常需要把内部动作转账、计数变更、状态迁移暴露成外部可以查询的事件并希望能按某个字段比如交易 ID、发送者地址过滤这些事件。Sway 用两个属性完成这件事#[event]把一个 struct 或 enum 标记为合约可发出的事件#[indexed]把事件 struct 的指定字段标记为索引字段从而支持基于这些字段值的高效过滤与检索。本文基于 Sway 官方文档 Attributes 参考给出定义事件、发出事件、构建验证的完整路径。先弄清两个属性的规则#[event]用于 struct 和 enum#[event] struct MyEventStruct { #[indexed] id: u64, sender: Identity, } #[event] enum MyEventEnum { A: (), B: (), }这是 attributes.md 中的原始示例id字段被标记为#[indexed]外部就可以按id的值过滤事件。使用#[indexed]时有两条硬规则违反会导致编译失败顺序要求indexed 字段必须顺序地应用于 struct 的开头一组字段上即不能先出现普通字段、再出现#[indexed]字段。类型要求#[indexed]只能用于 exact size ABI 类型文档列出的类型包括boolu8、u16、u32、u64、u256numericb256Addressstr[N]仅包含 exact size 类型的元组仅包含 exact size 类型的 struct字面量长度的 exact size 类型数组指向 exact size 类型的类型别名另外#[event]还会把事件类型包含进合约的 JSON ABI 表示供链下工具解析事件时使用。如何发出事件定义好事件类型后通过标准库的log函数发出事件值。Sway 测试套件中的 事件示例脚本 展示了这一用法script; #[event] pub struct TestEventStruct { field_0: bool, field_1: u64, } #[event] pub struct TestIndexedEventStruct { #[indexed] field_0: bool, #[indexed] field_1: bool, } fn main() { let event_struct TestEventStruct { field_0: true, field_1: 10u64, }; log(event_struct); let indexed_event_struct_true TestIndexedEventStruct { field_0: true, field_1: true, }; log(indexed_event_struct_true); }注意这个示例里TestIndexedEventStruct的两个字段都标了#[indexed]符合顺序应用于开头字段的规则。log来自std::logging合约脚本中按常规方式导入即可。日志文档说明每次log调用会向 receipts 列表追加一条Log或LogDatareceipt非引用类型bool、u8、u16、u32、u64产生Logreceipt引用类型及大于 64 位的非引用类型如u256产生LogDatareceipt。构建并在 ABI 中确认事件类型在项目根目录执行forc build构建合约。构建成功后out/debug/下会生成合约的 JSON ABI 文件例如 Forc Call 文档中使用的./out/debug/counter-contract-abi.json这类路径。验证点打开生成的 ABI JSON确认里面包含了你声明的事件类型——这是#[event]属性的直接效果causes the event types to be included in the JSON ABI representation for the contract。ABI 中带有事件类型SDK 才能在链下按类型解码收到的日志。调用时观察发出的事件部署合约后用forc call调用触发事件的方法并用-vv提升日志级别。根据 Forc Call 文档verbosity 2 及以上-vv会输出事务 trace其中包含Emitted logs and eventstrace 中emit data行就是合约发出的 log/事件例如文档示例中的│ ├─ emit AsciiString { data: incremented count } │ ├─ emit 2如果你只关心解码后的日志-v级别即可显示 decoded logs-vvv会额外显示 receipts 和 script JSON。Log/LogDatareceipt 长什么样comments_and_logging 文档给出了文档示例数值仅为示例不是固定预期Log: { id: 0000000000000000000000000000000000000000000000000000000000000000, is: 10352, pc: 10404, ra: 42, rb: 1018205, rc: 0, rd: 0 }其中ra保存被记录的数值rb是一个 log 实例的唯一 IDRust 和 TS SDK 用它到 JSON ABI 中查日志 ID 来判断数据类型从而把日志值还原成可读形式。限制与易错点#[indexed]只能加在带#[event]的struct字段上enum 事件如MyEventEnum没有字段可加索引。indexed 字段类型不在 exact size ABI 类型清单内、或字段顺序不连续中间夹了未索引字段都会编译失败。文档没有说明不同 Fuel 版本对事件编码的行为差异如果你的构建启用了实验特性以编译器实际报错为准。下一步log产生的 receipt 可以被 Rust 和 TS SDK 按 JSON ABI 解码展示comments_and_logging 文档末尾注明了 SDK 提供了基于 JSON ABI 读取并展示日志值的 API。结合#[indexed]字段链下即可按索引字段值过滤你合约发出的事件。【免费下载链接】sway Empowering everyone to build reliable and efficient smart contracts.项目地址: https://gitcode.com/GitHub_Trending/sw/sway创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考