编写第一个 Anchor 程序 - 第 1 部分

  • QuickNode
  • 发布于 2024-07-08 09:45
  • 阅读 189

编写第一个 Anchor 程序

概述

程序是 Solana 所称的智能合约——它们是处理信息和请求的引擎:从代币转移和糖果机铸造到“Hello World”日志和 DeFi 代管治理。Solana 支持使用 Rust、C 和 C++ 编程语言编写链上程序。Anchor 是一个加速在 Solana 上构建安全 Rust 程序的框架。让我们用 Anchor 构建你的第一个 Solana 程序吧!

你将做什么

在这个两部分的指南中,你将使用 Anchor 和 Solana Playground 创建你的第一个 Solana 程序,这是一个用于编译和部署 Solana 程序的网页工具。你将:

  • 初始化一个新的 Solana 程序
  • 部署一个新的程序到 Solana 的 Devnet
  • 创建并发送一条“Hello World”消息
  • 实现一个增量函数来跟踪你的程序被使用的次数(第 2 部分)

你需要什么

  • Solana 基础知识 的基本了解
  • 对 JavaScript/TypeScript 和 Rust 编程语言的基本了解
  • 一个现代网页浏览器(例如,Google Chrome

初始化你的项目

通过访问 https://beta.solpg.io/ 在 Solana Playground 中创建一个新项目。Solana Playground 是一个基于浏览器的 Solana 代码编辑器,可以让我们迅速启动这个项目。你也可以在自己的代码编辑器中跟着做,但本指南将根据 Solana Playground 的要求步骤进行调整。首先,点击“创建新项目”:

输入项目名称“Hello World”,并选择“Anchor (Rust)”:

点击“创建”按钮。Solana Playground 将初始化你的项目。打开 lib.rs 并从第 7 行开始删除默认文本,删除 declare_id! 语句后面的部分。你的环境应如下所示:

创建并连接钱包

由于这个项目只是为了演示,我们可以使用一个“临时”钱包。Solana Playground 让创建一个钱包变得简单。你应该会看到浏览器窗口左下角的红点“未连接”。点击它:

Solana Playground 将为你生成一个钱包(或者你可以导入自己的钱包)。如果喜欢,可以随时保存以便后续使用,当你准备好时点击继续。一个新钱包将被初始化并连接到 Solana devnet。Solana Playground 会自动向你的新钱包空投一些 SOL,但我们将请求额外的以确保有足够的资金来部署我们的程序。在浏览器终端中,你可以使用 Solana CLI 命令。输入 solana airdrop 2 向你的钱包空投 2 SOL。你的钱包现在应该已经连接到 devnet,余额为 6 SOL:

你准备好了!让我们开始构建吧!

Hello World

创建你的程序

打开 lib.rs(所有 Solana 链上 Rust 程序的基础库)。我们保留了模板中的两行代码:

  1. *use anchor_lang::prelude::;** 导入 Anchor 的关键特性。
  2. declare_id!("11111111111111111111111111111111"); 设置你程序的公钥。默认值是一个由 1 组成的字符串,会在构建我们的程序时被覆盖。

下面,使用 #[program] 模块创建你的 hello_world 程序(这里将包含我们所有的逻辑):

#[program]
mod hello_world {
    use super::*;
}

我们定义了一个新的模块 hello_world,使用 program 模块和 use super 以允许我们使用父模块 (program) 的元素。

在你的 hello_world 模块之后,使用 #[derive(Accounts)] 创建一个新的账户结构 SayHello。这个初始结构不需要传入任何账户,因为我们只是想记录一条消息:

#[derive(Accounts)]
pub struct SayHello {}

最后,我们需要一个可以从前端调用的函数。在 hello_world 中,use super 之后声明一个函数 say_hello

    pub fn say_hello(_ctx: Context<SayHello>) -> Result<()> {
        msg!("Hello World!"); // Message will show up in the tx logs
        Ok(())
    }

这个函数将使用 msg! 将消息记录到 Solana 程序日志中,并通过调用 Ok(()) 返回一个成功值。你的 Hello World 程序应如下所示:

use anchor_lang::prelude::*;

declare_id!("11111111111111111111111111111111");

#[program]
mod hello_world {
    use super::*;
    pub fn say_hello(_ctx: Context<SayHello>) -> Result<()> {
        msg!("Hello World!");       
        Ok(())
    }
}

#[derive(Accounts)]
pub struct SayHello {}

编译并部署你的程序

点击屏幕左侧的 🔧 Build 以编译你的代码并检查错误。你应该在控制台中看到如下日志:

你应该注意到你的 declare_id! 现在有了一个公钥——这就是将用于你的程序的密钥。

最后,让我们将其部署到 Devnet。点击页面左侧的工具图标 🛠,然后点击“部署”:

这可能需要一分钟或两分钟,但完成后,你应该在浏览器终端中看到类似这样的内容:

从客户端调用你的程序

返回到“文件”标签。你可能已经注意到 Solana Playground 有一个客户端部分。这是一个直接从同一窗口与我们的程序交互的便捷方式。继续展开“client”切换,并打开 client.ts

我们将使用 TypeScript 编写一个简单的函数来调用我们的 say_hello 函数。将 client.ts 中的代码替换为:

console.log(pg.wallet.publicKey.toString(), "saying hello:");
// Fetch the latest blockhash
let latestBlockhash = await pg.connection.getLatestBlockhash('finalized');

// Create a Solana transaction for the say_hello method
const tx = await pg.program.methods
  .sayHello()
  .transaction();

// Send and confirm the transaction and log the tx URL
const txid = await web3.sendAndConfirmTransaction(pg.connection, tx, [pg.wallet.keypair])
console.log('Transaction Complete: ',`https://explorer.solana.com/tx/${txid}?cluster=devnet`);  

这是我们在这里所做的事情的分解:

  1. 获取最新的区块哈希。

  2. 使用 Anchor 的有用工具,我们调用我们的 say_hello 方法(请注意,在 TypeScript 中它被格式化为 sayHello)。Anchor 实际上在后台做了很多事情。首先,pg.program 通过 IDL(交互式数据语言)与我们的程序建立了连接,这实际上是一个 .json 文件,将你的 rust 程序映射到可以被客户端调用的方法。我们将在另一个指南中详细介绍它们,但如果你想查看项目的 IDL,可以在项目的 "🛠 Build & Deploy" 标签中访问它。如果你之前在 Solana 上开发过,你可能会注意到我们的方法在交易中没有传递任何账户。由于 Anchor 知道我们正在调用哪个程序,因此它在后台为我们处理这些事情。

  3. 最后,我们等待集群确认交易并记录结果。

请点击左侧边栏中的 "▶️ Run"。你应该会看到你的交易 URL 的日志:

点击它并滚动到 Solana Explorer 上交易日志的底部。你好?

干得好!你现在有一个可以让客户端与集群交互的程序。

总结

做得不错,恭喜你完成了第一个 Solana 程序!这是你成为 Solana 开发者道路上的重要第一步。想继续构建吗?在 本指南的第二部分 中,我们将为这个程序添加功能,以在链上存储我们调用 hello_world 的次数。

其他资源

我是 AI 翻译官,为大家转译优秀英文文章,如有翻译不通的地方,在这里修改,还请包涵~

点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
QuickNode
QuickNode
江湖只有他的大名,没有他的介绍。