本文介绍了 Solana 中的日志和事件机制,解释了如何通过事件在前端传递信息,以及如何查询 Solana 的交易历史。与以太坊不同,Solana 的事件不能用于历史查询,而是更适合实时监听。
Solana 程序可以发出事件,类似于 Ethereum 发出事件,不过我们会讨论其中的一些差异。
具体而言,Solana 中的事件旨在将信息传递给前端,而不是记录过去的交易。如需获取历史记录,可以通过地址查询 Solana 交易。
下面的程序有两个事件:MyEvent
和 MySecondEvent
。与 Ethereum 事件有“参数”类似,Solana 事件在结构体中有字段:
use anchor_lang::prelude::*;
declare_id!("FmyZrMmPvRzmJCG3p5R1AnbkPqSmzdJrcYzgnQiGKuBq");
#[program]
pub mod emit {
use super::*;
pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
emit!(MyEvent { value: 42 });
emit!(MySecondEvent { value: 3, message: "hello world".to_string() });
Ok(())
}
}
#[derive(Accounts)]
pub struct Initialize {}
#[event]
pub struct MyEvent {
pub value: u64,
}
#[event]
pub struct MySecondEvent {
pub value: u64,
pub message: String,
}
事件成为 Solana 程序的 IDL 的一部分,类似于事件是 Solidity 智能合约 ABI 的一部分。下面我们截图了上面程序的 IDL,并高亮显示了相关部分:
在 Solana 中没有类似于 Ethereum 的“索引”和“非索引”信息(即使在上面的截图中有一个“索引”字段,它也没有用)。
与 Ethereum 不同,我们不能直接根据区块编号的范围查询过去的事件。我们只能在事件发生时进行监听。(稍后我们将看到 Solana 的审计过去交易的方法)。下面的代码展示了如何在 Solana 中监听事件:
import * as anchor from "@coral-xyz/anchor";
import { BorshCoder, EventParser, Program } from "@coral-xyz/anchor";
import { Emit } from "../target/types/emit";
describe("emit", () => {
// 配置客户端以使用本地集群。
anchor.setProvider(anchor.AnchorProvider.env());
const program = anchor.workspace.Emit as Program<Emit>;
it("已初始化!", async () => {
const listenerMyEvent = program.addEventListener('MyEvent', (event, slot) => {
console.log(`槽 ${slot} 事件值 ${event.value}`);
});
const listenerMySecondEvent = program.addEventListener('MySecondEvent', (event, slot) => {
console.log(`槽 ${slot} 事件值 ${event.value} 事件消息 ${event.message}`);
});
await program.methods.initialize().rpc();
// 这行仅用于测试,确保事件监听器有时间来监听事件。
await new Promise((resolve) => setTimeout(resolve, 5000));
program.removeEventListener(li...
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!