用IDL加速Solana应用开发

在这篇文章中,我们将探讨Interface Definition Language (IDL)是什么以及它们如何成为改善Solana开发体验的重要部分。本文

用IDL加速Solana应用开发
一键发币: SUI | SOL | BNB | ETH | BASE | ARB | OP | POLYGON | AVAX | FTM | OK

Solana因其独特的架构而获得了市场上最快和最具可扩展性的区块链的声誉,能够实现高吞吐量和低延迟。然而,随着这种规模的增长,生态系统中的一个重要组成部分需要持续关注:开发者体验(DX)。改善开发者体验一直是焦点,因为开发者和建设者是Solana的生命线。

目前,Solana开发者在现有基础设施中发现和实施IDLs时面临许多问题。两个主要的问题被广泛讨论:

  • 读取网络数据很困难,尤其是对于非Anchor程序
  • CPI的不透明性带来了安全方面的担忧

在这篇文章中,我们将探讨Interface Definition Language (IDL)是什么以及它们如何成为改善Solana开发体验的重要部分。本文旨在全面理解IDL在Solana开发领域的角色,并解释为什么进一步了解提高其可发现性将有助于加速Solana上的开发体验。

1、接口描述语言(IDL)

在Solana中,接口定义语言(IDL)指的是一个程序的公共接口。它代表了程序账户、指令以及错误代码的结构。通常以JSON和TypeScript文件格式存在,并用于生成客户端代码,使客户端能够轻松地与Solana程序交互。对于用Anchor编写的程序,IDL会自动生成。IDL可以与EVM的ABI文件相比较,为开发者提供对程序结构的易理解性。

为什么IDL非常有用?

虽然IDL的应用可以列举到各种不同的用例,但它们的主要优点在于:

1.1 使程序交互人性化

通过IDL,我们可以解密一系列字节的交易和账户,使开发者能够轻松解析指令或账户,从而更好地理解程序在做什么。这一属性使得独立开发者和专业开发者能够在探索器、消费者UI和数据平台(如Dune)上实现平滑的集成。以下是一个Solana上解析交易指令的例子:

以下是Solana探索器显示公共IDL的一个例子:

1.2 提供标准接口

通过利用标准接口,工具和框架可以更容易地生成指令来与程序交互,因此可以更轻松地实现程序接口之间的组合,使构建客户端代码变得更加简单。例如,嵌入式钱包提供商可以通过特定的ix区分符进行白名单处理。下面,我们有两个使用Native Solana和Anchor创建问候账户的前端示例:

使用原生Solana:

const GREETING_SEED = 'hello'
const greetedPubkey = await PublicKey.createWithSeed(
    payer.publicKey,
    GREETING_SEED,
    programId
)

// 检查问候账户是否已经创建
const greetedAccount = await connection.getAccountInfo(greetedPubkey)
if (greetedAccount === null) {
    console.log('创建账户', greetedPubkey.toBase58(), '以说你好')
    const lamports = await connection.getMinimumBalanceForRentExemption(
        GREETING_SIZE
    )

    const transaction = new Transaction().add(
        SystemProgram.createAccountWithSeed({
            fromPubkey: payer.publicKey,
            basePubkey: payer.publicKey,
            seed: GREETING_SEED,
            newAccountPubkey: greetedPubkey,
            lamports,
            space: GREETING_SIZE,
            programId,
        })
    )
    await sendAndConfirmTransaction(connection, transaction, [payer])
}
// ...
export async function sayHello(): Promise<void> {
    console.log('向', greetedPubkey.toBase58(), '问好')
    const instruction = new TransactionInstruction({
        keys: [{ pubkey: greetedPubkey, isSigner: false, isWritable: true }],
        programId,
        data: Buffer.alloc(0), // 所有指令都是问好
    })
    await sendAndConfirmTransaction(
        connection,
        new Transaction().add(instruction),
        [payer]
    )
}

使用Anchor:

const anchor = require('@project-serum/anchor')

async function greet(message: string) {
    anchor.setProvider(anchor.Provider.local())
    // 这里我们加载HelloAnchor示例IDL
    const program = anchor.workspace.HelloAnchor
    let greetKey = Keypair.generate()
    await program.methods
        .initialize(message)
        .accounts({
            newAccount: greetKey.publicKey,
            signer: wallet.publicKey,
            systemProgram: web3.SystemProgram.programId,
        })
        .signers([wallet, greetKey])
        .rpc()
}

greet('Hello World')

通过使用IDL,Anchor可以抽象化过程,使其更易于阅读、更快部署并且更容易进行CPI交互。要了解更多关于CPI及其对Solana开发的重要性,请参阅这篇文章《跨程序调用和PDA——Anchor上的两种强大机制的结合》

1.3 无依赖SDK

IDL提供了无依赖SDK,用于Solana长尾程序的declare_program!()

2、创建IDL

使用Anchor时,由于IDL对整个Anchor编程环境至关重要,因此在构建时会自动生成。从Anchor项目目录中,在终端输入以下命令:

anchor build --idl <IDL_OUTPUT_DIRECTORY>

默认情况下,idl.json将保存在./target/idl文件夹中

对于用原生Rust编写的Solana程序,可以使用工具如Metaplex ShankCodama Kinobi生成IDL。

3、发布IDL

使用Anchor也可以轻松地将IDL发布到链上。为此,只需在终端输入以下命令:

anchor idl init --filepath <FILEPATH> <PROGRAM_ID> --provider.cluster <CLUSTER> --provider.wallet <WALLET>

确保使用的钱包是程序授权者,并且有足够的SOL用于链上交易! 加载IDL后,你应该可以在Solana Explorer上看到该IDL,网址为:

https://explorer.solana.com/address/YOUR_PROGRAM_ID/anchor-program

Anchor的idl命令还有其他一些方便的工具,可以帮助开发者获取、更新或冻结IDL。有关这些命令的详细信息,可以在终端输入以下命令:

anchor idl -h

4、客户端接口的IDL

在你的IDL中定义的程序映射到由生成的TypeScript模块提供的函数,该模块集成到我们的应用程序前端。此模块的一般结构如下所示:

import { Program, AnchorProvider, setProvider } from '@project-serum/anchor'
import { Connection, KeyPair } from '@solana/web3.js'
import { PROGRAM_ID, IDL } from './your-program-dir'
// 其中IDL是anchor build生成的.json文件
// 和PROGRAM_ID是您的链上程序ID

export const yourFunction = async () => {
    const wallet = KeyPair.generate()
    const connection = new Connection(QN_ENDPOINT)
    const provider = new AnchorProvider(connection, wallet, {})
    setProvider(provider)
    const program = new Program(IDL, PROGRAM_ID)
    // ...您的代码
    // 例如await program.methods.yourMethod(YOUR_PARAMETERS).accounts({YOUR_ACCOUNTS}).rpc();
}

由于IDL中嵌入了程序指令和账户,代码编辑器可以自动检测可调用的程序通过program.methods...。放置了一个类型保护以确保所有必要的账户都传递给指令。请参阅Intro to client-side Anchor development

5、提高IDL的可发现性

目前大多数程序使用Anchor,而对于非Anchor框架,codama配合验证构建可以填补空白。这些IDL提供了高效的读取和调用程序的起点,但目前它们还不具备可发现性。尚不确定IDL是否能覆盖所有程序的可能性,但大多数程序都可以被覆盖。

当前提出的改进可发现性的解决方案必须满足以下要求:

  • 必须允许从网络中进行通用读取。
  • 实现CPI到其他程序的时间应显著减少。
  • 程序发现应尽可能无缝。

6、结束语

我们探讨了IDL及其众多好处。我们也研究了Anchor和非Anchor框架中的IDL,以及开发者如何利用它们来提高程序的可组合性。

然而,现有的基础设施没有基于部署时间的版本化IDL,这使得关注一致数据集成的开发者难以理解在哪个槽位使用哪个IDL。

提高IDL的可发现性具有巨大的好处;开发者可以更容易地将CPI集成到程序中,从而扩大整个开发领域内的可组合性,解锁可能尚未想到的新用例。

可发现的IDL还提供了更多关于安全缺陷的见解,因为即使是Solana上的资深开发者也倾向于通过隐藏来保护他们的程序,这往往证明是一种缺陷而不是特性。

在未来几年中,IDL开始在聚光灯下占据一席之地,成为更多投资和开发的目标,以便使在Solana上构建成为一个更加框架和语言无关的过程,从而加速Solana上所有开发领域的开发者体验


原文链接:Improving IDLs Discoverability: Accelerating Solana Development, Integration and Composability

DefiPlot翻译整理,转载请标明出处

免责声明:本站资源仅用于学习目的,也不应被视为投资建议,读者在采取任何行动之前应自行研究并对自己的决定承担全部责任。
通过 NowPayments 打赏