IDL 是 接口定义语言(Interface Definition Language) 的缩写。 在 Solana 上,IDL 是描述程序接口的 JSON 文件。它们允许浏览器和用户解码程序指令、账户数据和程序错误,并提供以不同编程语言生成客户端的可能性。
为什么 IDL 至关重要
- 标准化 → 为程序接口提供统一格式。
- 开发者体验 → 自动生成客户端 SDK。
- 可组合性 → 其他开发者无需阅读源代码即可与你的程序交互。
- 可读性 → 任何人都可以在浏览器中读取程序指令和账户数据,无需阅读程序源代码。
IDL 的用途
解码指令与账户数据
所有浏览器都使用程序 IDL 来解码指令和账户数据。在此你可以看到 Solana Explorer UI 中的
Anchor 0.30.1
以及
Legacy IDL
示例。在
这笔交易
中,你可以看到 2048 游戏已解码的指令,包括 pushInDirection 及其方向。
你可以在 TypeScript 客户端中使用 Solana JS 工具函数 来解码指令和账户数据。
解析账户变更
你可以通过生成的 TypeScript 类型轻松订阅程序中的账户变更。
import { Connection } from "@solana/web3.js";const connection = new Connection("https://api.devnet.solana.com");// Fetch account onceconst account = await program.account.counter.fetch(counterPda);// Subscribe via websocket to account changesprogram.account.counter.subscribe(counterPda).on("change", (account) => {console.log("Account changed:", account);});// Or use decoder to decode any account or instruction dataconnection.onAccountChange(counterPda, (accInfo) => {console.log("Account changed:",program.coder.accounts.decode("counterData", account.data));});
有关事件定义、订阅、日志与 CPI 解码、数据回填、模式版本控制及测试,请参阅 Anchor Events。
解码交易
你也可以在客户端中使用 Solana JS 工具函数 来解码交易,这将为你提供整笔交易的类型化对象。
构建你自己的客户端
借助 IDL,你可以用多种语言创建自己的客户端。只需找到你想交互的程序,下载其 IDL,然后即可用你偏好的语言生成客户端。
以下是一个用 TypeScript 生成客户端的示例。
Anchor 中的 IDL
如果你正在使用 Anchor 框架:
- 构建程序时会自动生成 IDL。
- IDL 文件位于
target/idl/<program>.json。 - TypeScript 类型生成于
target/types/<program>.ts。 - 程序地址存储在 IDL 中(
idl.address)。
anchor buildcat 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:包含
accounts、args和discriminator的可调用方法。 - accounts:程序暴露的账户类型(含判别器)。
- types:指令/账户引用的结构体/枚举/类型别名。
- events / errors / constants:事件、错误码和常量的可选定义。
注意:Anchor v0.30 引入了新的 IDL 规范。旧版 IDL(0.30 之前)在顶层使用
name、version字段,在账户中使用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 programdotnet tool install Solana.Unity.Anchor.Tool <- run oncedotnet 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 账户。Anchor 允许你通过向程序添加额外指令来上传和更新链上 IDL。这会增加程序的体积,这也是程序元数据程序被创建的原因。在程序元数据程序中,所有程序 IDL 以及 security.txt 信息(如名称、联系方式和图标)都存储在 程序元数据程序 的 PDA 中。
Anchor IDL 账户
Anchor 将 IDL 以 PDA 的形式保存在程序的链上。
- IDL 可上链存储至 Anchor IDL 账户。
- 这使得浏览器、钱包和 SDK 可以直接从 Solana 获取 IDL。
首次操作(初始化 IDL 账户):
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 账户的生成是无需许可的。因此请尽快上传你的 IDL,然后设置权限。
你可以在 Anchor 文档 中了解更多有关 Anchor IDL 账户的内容。
程序元数据程序(PMP)
程序元数据程序是一个允许你将程序 IDL 及 security.txt 信息(如名称、联系方式和图标)存储在链上的程序。这可能将成为未来链上存储 IDL 的标准方式。
npx @solana-program/program-metadata write idl <program-id> ./idl.json
你可以在 程序元数据程序文档 中了解更多相关内容。
注意:截至本文最后更新时,PMP 尚未得到所有浏览器的支持。
最佳实践
程序部署的最佳实践是使用 Squads 等多签方案,并借助 Solana GitHub Actions 工作流 使整个流程尽可能便捷。
如此一来,程序将自动完成升级、IDL 上传、构建验证,并生成一笔交易提案,供你的多签方案签名和部署程序。
- 保持 IDL 更新 → 每次修改程序时都要更新 IDL。
- 将 IDL 上传到链上 → 以提高透明度并支持工具生态。
- 记录自定义错误 → 改善客户端的用户体验。
- 验证构建 → 确保 IDL 与已部署的程序一致。
IDL 版本管理
目前使用 Anchor 时,链上每次只能有一个版本的 IDL。这意味着如果你需要修改程序,就必须上传新版本的 IDL,最好与程序升级同步进行。如果客户端尚未更新,这可能会导致问题,这也是编写程序元数据程序的原因之一。使用 PMP,你将能够为程序设置不同的种子(seed)并以此实现版本控制。该设计目前尚未完全定型,欢迎讨论。
延伸阅读
- Anchor IDL 文档 → 自动生成 IDL 和客户端。(TypeScript、C#、Python)
- Codama → IDL 工具链 + 客户端生成器(Rust、JS/TS、Umi/Kit 等)。
- 程序元数据程序 → 将 IDL 和 security.txt 信息存储到链上。
以上就是 Solana 上 IDL 的基础知识。IDL 是链上程序与链下客户端之间的桥梁,支撑起了你今天所见的丰富工具和 SDK 生态系统。
Is this page helpful?