Solana 文档开发程序

IDL——易于使用的程序接口

IDL 是接口定义语言(Interface Definition Language)的缩写。 在 Solana 上,IDL 是描述程序接口的 JSON 文件。它们允许区块链浏览器和用户解码程序指令、账户数据和程序错误,并提供以不同编程语言生成客户端的能力。


为什么 IDL 很重要

  • 标准化 → 为程序接口提供统一的格式。
  • 开发者体验 → 自动生成客户端 SDK。
  • 可组合性 → 其他开发者无需阅读源代码即可与你的程序进行交互。
  • 可读性 → 任何人都可以在区块链浏览器中读取程序指令和账户数据,而无需阅读程序源代码。

IDL 的用途

解码指令和账户数据

所有区块链浏览器都使用程序 IDL 来解码指令和账户数据。在此你可以看到 Solana Explorer UI 中 Anchor 0.30.1Legacy IDL 的示例。在 这笔交易 中,你可以看到 2048 游戏的已解码指令,包括 pushInDirection 及其方向。

你可以通过使用 Solana JS 工具库 在 TypeScript 客户端中解码指令和账户数据。

解析 Anchor 事件或账户变更

你可以使用生成的 TypeScript 类型轻松订阅程序中的账户变更。

import { Connection } from "@solana/web3.js";
const connection = new Connection("https://api.devnet.solana.com");
// Fetch account once
const account = await program.account.counter.fetch(counterPda);
// Subscribe via websocket to account changes
program.account.counter.subscribe(counterPda).on("change", (account) => {
console.log("Account changed:", account);
});
// Or use decoder to decode any account or instruction data
connection.onAccountChange(counterPda, (accInfo) => {
console.log(
"Account changed:",
program.coder.accounts.decode("counterData", account.data)
);
});

例如,你可以在程序中触发 Anchor 事件,然后记录这些事件、将其写入数据库,或用它们向 Telegram 群组发送消息。

// Emit the purchase event
emit!(PurchaseMade {
buyer: *ctx.accounts.signer.key,
product_name: name,
price,
timestamp: Clock::get()?.unix_timestamp,
table_number,
receipt_id,
telegram_channel_id: ctx.accounts.receipts.telegram_channel_id.clone(),
store_name: ctx.accounts.receipts.store_name.clone(),
receipts_account: ctx.accounts.receipts.key(),
});

为此,你可以使用 Solana JS 工具库 来解析事件。这里有一个 示例实现, 它利用 Anchor 事件向 Telegram 群组发送消息。

解码交易

你也可以在客户端中使用 Solana JS 工具库 解码交易,这将为你提供整笔交易的类型化对象。

构建自己的客户端

使用 IDL,你可以用多种语言创建自己的客户端。只需找到你想交互的程序,下载其 IDL,然后即可用你偏好的语言生成客户端。

这里有一个如何用 TypeScript 生成客户端的示例

Anchor 中的 IDL

如果你正在使用 Anchor 框架

  • 构建程序时会自动生成 IDL。
  • IDL 文件位于 target/idl/<program>.json
  • TypeScript 类型生成于 target/types/<program>.ts
  • 程序地址存储在 IDL 中(idl.address)。
anchor build
cat target/idl/counter.json

IDL 的结构剖析

以下是一个最简示例(Anchor v0.30+ 规范):

{
"address": "6khKp4BeJpCjBY1Eh39ybiqbfRnrn2UzWeUARjQLXYRC",
"metadata": {
"name": "counter",
"version": "0.1.0",
"spec": "0.1.0"
},
"instructions": [
{
"name": "increment",
"discriminator": [11, 18, 104, 9, 104, 174, 59, 33],
"accounts": [{ "name": "counter", "writable": true }],
"args": []
}
],
"accounts": [
{
"name": "Counter",
"discriminator": [255, 176, 4, 245, 188, 253, 124, 25]
}
],
"types": [
{
"name": "Counter",
"type": {
"kind": "struct",
"fields": [{ "name": "count", "type": "u64" }]
}
}
]
}
  • address:链上程序 ID。
  • metadata:关于程序/接口的 { name, version, spec, ... } 信息。
  • instructions:包含 accountsargsdiscriminator 的可调用方法。
  • accounts:程序公开的账户类型(含判别器)。
  • types:指令/账户引用的结构体/枚举/类型别名。
  • events / errors / constants:事件、错误码和常量的可选定义。

注意:Anchor v0.30 引入了新的 IDL 规范。旧版 IDL(v0.30 之前)在顶层使用 nameversion 等字段,并在账户中使用 isMut/isSigner。 你可以使用 anchor idl convert 转换旧版 IDL,或使用 Anchor v0.30+ 重新构建。如果你需要即时将旧版 IDL 转换为新规范,也可以使用这段 转换代码。 例如,如果你维护一个 Solana 区块链浏览器并希望保持向后兼容性,这将非常有用。


TypeScript 客户端

Anchor 还会自动为你生成 TypeScript 客户端。你可以在 target/types 文件夹中找到生成的客户端。

然后在你的客户端(TypeScript,v0.30+)中,你可以像这样轻松调用程序指令并获取账户:

import { AnchorProvider, Program } from "@coral-xyz/anchor";
import idl from "./counter.json";
const provider = AnchorProvider.local();
const program = new Program(idl, provider);
await program.methods.increment().rpc();

C# 客户端

要生成 C# 客户端,你可以使用以下命令:

cd program
dotnet tool install Solana.Unity.Anchor.Tool <- run once
dotnet anchorgen -i target/idl/counter.json -o target/idl/Counter.cs

你可以在 Solana 游戏预设游戏文档 中了解更多关于如何在 Unity 中使用 C# 客户端进行交互的内容。

Python 客户端

对于 Python,你可以使用 AnchorPy 库。

未来将通过 Codama 渲染器提供更多客户端生成器。


不使用 Anchor 的 IDL

并非所有程序都使用 Anchor 构建。 对于原生 Solana 程序:

  • 一个名为 Codama 的工具目前正在开发中,用于通过宏从 Rust 生成 IDL,或通过转换 Anchor IDL 来生成。这里有一个进行中的 Codama 宏 示例,用于生成 Codama IDL。Codama 可将 Anchor/Shank IDL 转换为 Codama IDL。若要获取 Anchor IDL,请使用 Anchor 生成(或对旧版项目使用 anchor idl convert)。
  • 在 Codama 宏完全就绪之前,你也可以使用 Metaplex Shank 生成 Shank IDL,然后将其转换为 Codama IDL。
  • 你也可以手动编写 IDL(Anchor 或 Codama 格式),但这并不十分可靠。Cursor 等 AI 工具可以帮助你编写 IDL,但你应始终对照程序源代码验证 IDL,更好的方式是使用 Anchor、Codama 或 Metaplex Shank。

链上存储 IDL

有两种方式可以将 IDL 上传至链上。最常用的标准方式是 Anchor IDL account。Anchor 通过向程序添加额外指令来支持链上上传和更新 IDL,但这会增加程序的体积,这也是 program metadata program 被创建的原因。在 program metadata program 中,所有程序 IDL 以及 security.txt 信息(如名称、联系方式和图标)都存储在 program metadata program 的 PDA 中。

Anchor IDL Account

Anchor 将 IDL 以你程序的 PDA 形式保存在链上。

  • IDL 可以链上上传至 Anchor IDL account。
  • 这使得区块链浏览器、钱包和 SDK 能够直接从 Solana 获取 IDL。

首次使用(初始化 IDL account):

anchor idl init <PROGRAM_ID> -f target/idl/counter.json --provider.cluster devnet

升级(由授权方进行后续更新):

anchor idl upgrade <PROGRAM_ID> -f target/idl/counter.json --provider.cluster devnet

常用相关命令:

anchor idl fetch -o idl.json <PROGRAM_ID>
anchor idl authority <PROGRAM_ID>
anchor idl set-authority -p <PROGRAM_ID> -n <NEW_AUTHORITY>
anchor idl erase-authority -p <PROGRAM_ID>

请注意,默认情况下 Anchor IDL account 的生成是无需许可的。因此请尽快上传你的 IDL,然后设置授权方。

你可以在 Anchor 文档 中了解更多关于 Anchor IDL account 的内容。

Program Metadata Program(PMP)

program metadata program 是一个允许你将程序 IDL 和 security.txt 信息(如名称、联系方式和图标)存储在链上的程序。这可能将成为未来链上存储 IDL 的标准方式。

npx @solana-program/program-metadata write idl <program-id> ./idl.json

你可以在 program metadata program 文档 中了解更多关于 program metadata program 的内容。

注意:截至本文最后更新时,PMP 尚未得到所有区块链浏览器的支持。


最佳实践

程序部署的最佳实践是使用像 Squads 这样的多签方案,并通过 Solana GitHub Actions 工作流 使这一流程尽可能自动化。

这样,程序将自动完成升级、IDL 上传、构建验证,然后生成一笔待多签成员签名并部署程序的交易提案。

  1. 保持 IDL 更新 → 每次修改程序时务必更新 IDL。
  2. 将 IDL 上链存储 → 以确保透明度和工具支持。
  3. 记录自定义错误 → 提升客户端的用户体验。
  4. 验证构建 → 确保 IDL 与已部署的程序相匹配。

IDL 版本管理

目前使用 Anchor 时,链上同一时间只能保存一个版本的 IDL。这意味着如果你想对程序进行更改,需要上传新版本的 IDL,最好与程序升级同时进行。如果客户端尚未更新,这可能会导致问题,这也是 program metadata program 被开发出来的原因之一。使用 PMP,你将能够为程序设置不同的种子(seeds)并以此实现版本管理。该设计目前尚未完全定稿,欢迎讨论。


延伸阅读

  • Anchor IDL 文档 → 自动生成 IDL 和客户端(TypeScript、C#、Python)。
  • Codama → IDL 工具链 + 客户端 生成器(Rust、JS/TS、Umi/Kit 等)。
  • Program Metadata Program → 将 IDL 和 security.txt 信息存储在链上。

以上就是 Solana 上 IDL 的基础知识。IDL 是链上程序与链下客户端之间的桥梁,支撑着你今天所见的丰富工具和 SDK 生态系统。

Is this page helpful?

©️ 2026 Solana 基金会版权所有