您的位置:首页 > 房产 > 建筑 > 百度seo最成功的优化_新乡网站制作_属性词 关键词 核心词_免费推广的平台

百度seo最成功的优化_新乡网站制作_属性词 关键词 核心词_免费推广的平台

2025/5/10 17:53:12 来源:https://blog.csdn.net/2408_87746709/article/details/146422804  浏览:    关键词:百度seo最成功的优化_新乡网站制作_属性词 关键词 核心词_免费推广的平台
百度seo最成功的优化_新乡网站制作_属性词 关键词 核心词_免费推广的平台

本文将带你探索 Anchor 框架中的 IDL(接口定义语言),这是一个自动生成的 JSON 文件,用于描述 Solana 程序的接口。我们将通过示例展示 IDL 的作用,解释 TypeScript 测试如何调用程序函数。


什么是 IDL?

IDL(Interface Definition Language)是 Anchor 生成的程序接口定义,存储在 target/idl/<program_name>.json 中,类似于 Solidity 的 ABI。它列出了程序的公共函数(instructions)、参数(args)和账户要求(accounts),为客户端(如 TypeScript)提供与链上程序交互的蓝图。


示例 1:函数调用与 IDL 映射

初始化项目

创建一个新项目:

anchor init anchor-function-tutorial
cd anchor-function-tutorial

启动本地验证器:

solana-test-validator

修改函数名

将默认的 initialize 函数改为 boaty_mc_boatface。编辑 programs/anchor-function-tutorial/src/lib.rs:

use anchor_lang::prelude::*;declare_id!("3ytdGXdSqfQ5Z9NB9c5bGbkNqkzVPkpijs4hj4BeoAa7");#[program]
pub mod anchor_function_tutorial {use super::*;pub fn boaty_mc_boatface(ctx: Context<Initialize>) -> Result<()> {msg!("Boaty says hi!");Ok(())}
}#[derive(Accounts)]
pub struct Initialize {}

更新测试

编辑 tests/anchor-function-tutorial.ts:

it("Call boaty mcboatface", async () => {const tx = await program.methods.boatyMcBoatface().rpc();console.log("Your transaction signature", tx);
});

运行测试:

anchor test --skip-local-validator

测试如何定位函数?

Anchor 在构建时生成 IDL(target/idl/anchor_function_tutorial.json):

{"version": "0.1.0","name": "anchor_function_tutorial","instructions": [{"name": "boatyMcBoatface","accounts": [],"args": []}],"metadata": {"address": "3ytdGXdSqfQ5Z9NB9c5bGbkNqkzVPkpijs4hj4BeoAa7"}
}
  • 解析
    • "instructions":列出公共函数,类似 Solidity 的外部函数。
    • TypeScript 的 program.methods 根据 IDL 映射函数名,生成调用逻辑。

Anchor 0.30.x 后的命名规则

如果在 Anchor 0.30.0 及以上版本(如 0.30.1):

  • 函数名:保留 Rust 的蛇形命名(如 boaty_mc_boatface),不再转换为驼峰式(如 boatyMcBoatface)。
    • 原因:提升 Rust 代码与 IDL 的一致性,响应社区反馈。
  • 参数和账户名:仍使用驼峰式(如 firstArg、anotherSigner),适配 JavaScript/TypeScript 惯例。

测试调用注意

await program.methods.boatyMcBoatface();   // 正确,客户端仍需驼峰式
await program.methods.boaty_mc_boatface(); // 可行但不推荐
  • 经验建议:尽管 IDL 使用蛇形命名,建议在前端保持驼峰式调用,以符合生态习惯。

示例 2:带参数的算术函数

添加加减法函数

更新 lib.rs,实现加法和减法(Solana 不支持直接返回值,需用 msg! 输出):

use anchor_lang::prelude::*;declare_id!("3ytdGXdSqfQ5Z9NB9c5bGbkNqkzVPkpijs4hj4BeoAa7");#[program]
pub mod anchor_function_tutorial {use super::*;pub fn add(ctx: Context<Empty>, a: u64, b: u64) -> Result<()> {let sum = a + b;msg!("Sum is {}", sum);Ok(())}pub fn sub(ctx: Context<Empty>, a: u64, b: u64) -> Result<()> {let difference = a - b;msg!("Difference is {}", difference);Ok(())}
}#[derive(Accounts)]
pub struct Empty {}

更新测试

编辑 tests/anchor-function-tutorial.ts:

it("Should add", async () => {const tx = await program.methods.add(new anchor.BN(1), new anchor.BN(2)).rpc();console.log("Your transaction signature", tx);
});it("Should subtract", async () => {const tx = await program.methods.sub(new anchor.BN(10), new anchor.BN(3)).rpc();console.log("Your transaction signature", tx);
});

运行测试:

anchor test --skip-local-validator

生成的 IDL

  "instructions": [{"name": "add","accounts": [],"args": [{"name": "a","type": "u64"},{"name": "b","type": "u64"}]},{"name": "sub","accounts": [],"args": [{"name": "a","type": "u64"},{"name": "b","type": "u64"}]}],

账户结构体详解

Context 与结构体命名

函数中的 ctx: Context 指定账户上下文,T 是自定义结构体,名称(如 Initialize 或 Empty)任意,只要与函数签名一致。

#[derive(Accounts)] 的作用

这是 Anchor 的 Rust 属性宏,解析结构体字段并映射到 IDL 的 accounts。空结构体(如 Empty)生成空的 accounts 数组。

非空账户示例

更新 lib.rs:

use anchor_lang::prelude::*;declare_id!("3ytdGXdSqfQ5Z9NB9c5bGbkNqkzVPkpijs4hj4BeoAa7");#[program]
pub mod anchor_function_tutorial {use super::*;pub fn non_empty_account_example(ctx: Context<NonEmptyAccountExample>) -> Result<()> {msg!("Signers present");Ok(())}
}#[derive(Accounts)]
pub struct NonEmptyAccountExample<'info> {signer: Signer<'info>,another_signer: Signer<'info>,
}

构建:

anchor build

生成的 IDL 中的 instructions 部分为:

  "instructions": [{"name": "nonEmptyAccountExample","accounts": [{"name": "signer","isMut": false,"isSigner": true},{"name": "anotherSigner","isMut": false,"isSigner": true}],"args": []}]
  • 变化
    • 函数名:nonEmptyAccountExample(驼峰式)。
    • 账户名:signer 和 anotherSigner(another_signer 转为驼峰式)。
  • Signer:表示交易签名者,类似 Ethereum 的 tx.origin。

示例 3:综合应用

完整代码

use anchor_lang::prelude::*;declare_id!("3ytdGXdSqfQ5Z9NB9c5bGbkNqkzVPkpijs4hj4BeoAa7");#[program]
pub mod anchor_function_tutorial {use super::*;pub fn function_a(ctx: Context<NonEmptyAccountExample>) -> Result<()> {msg!("Function A called");Ok(())}pub fn function_b(ctx: Context<Empty>, first_arg: u64) -> Result<()> {msg!("Function B with arg {}", first_arg);Ok(())}
}#[derive(Accounts)]
pub struct NonEmptyAccountExample<'info> {signer: Signer<'info>,another_signer: Signer<'info>,
}#[derive(Accounts)]
pub struct Empty {}

生成的 IDL

{"version": "0.1.0","name": "anchor_function_tutorial","instructions": [{"name": "functionA","accounts": [{"name": "signer","isMut": false,"isSigner": true},{"name": "anotherSigner","isMut": false,"isSigner": true}],"args": []},{"name": "functionB","accounts": [],"args": [{"name": "firstArg","type": "u64"}]}]
}
  • 映射
    • functionA:无参数,账户来自 NonEmptyAccountExample。
    • functionB:参数 first_arg 转为 firstArg,账户为空。

教程到此结束,更多,请,,https://t.me/+_QibemQqIIg1OTY1

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com