在上一节中,我们通过Playground体验了Solana合约的开发和调用。本文将带你使用本地开发环境实现这一过程,并通过TypeScript调用合约。如果你已经按照之前的章节配置好本地开发环境,可以开始动手实践了!我们先用最简单的合约测试,然后用上一节的例子测试,可以学
在 上一节 中,我们通过 Playground 体验了 Solana 合约的开发和调用。本文将带你使用本地开发环境实现这一过程,并通过 TypeScript 调用合约。如果你已经按照 之前的章节 配置好本地开发环境,可以开始动手实践了!
我们先用最简单的合约测试, 然后用上一节的例子测试, 可以学习 ts 里面怎么创建 PDA 账户
确保本地开发环境为最新版本,运行以下命令升级:
agave-install update
你可能会疑惑:为什么是 agave
而不是 solana
?
其实,Solana Labs 的官方仓库已归档(archive),现在由 Anza 团队(由 Solana Labs 前高管和核心工程师组成)全面接手开发。Anza 的主要产品包括:
@solana/web3.js
的 2.0 版本。 而我们使用的 Anchor 框架则由 Backpack 钱包团队(coral-xyz)开发。
小贴士:原生 Rust 开发据说比 Anchor 更省 gas,但对于初学者来说,Anchor 的快速上手优势更重要。
solana config set -ud # 设置为开发网(devnet)
solana-keygen new # 生成默认钱包
solana airdrop 2 # 领取 2 SOL
solana-test-validator # 启动本地节点
localnet
快速验证,配合 Solana Explorer 查看本地交易。 solana ping
检查你与 RPC 的连接速度, 需要付 gas。初始化一个 Anchor 项目:
anchor init demo
cd demo
合约代码 lib.rs 我就不展示了, 就是最简单的 hello world, 大家自己看
solana 是部署之前就生成 Program Account 而不是部署完之后给你返回, 跟其他链不太一样
查看项目的 Program Address:
anchor keys list
# 或
solana address -k target/deploy/demo-keypair.json
两条命令结果一致,返回当前项目的 Program ID。
如果需要修改 Program Address:
场景:
solana-keygen new --outfile target/deploy/demo-keypair.json
solana address -k target/deploy/demo-keypair.json
lib.rs
:
anchor keys sync
注意:若不打算升级程序,可销毁私钥以确保安全。
anchor build
构建后,合约二进制文件生成在 target/deploy/demo.so
,后续部署的就是这个文件。
├── Anchor.toml # Anchor 配置文件
├── programs # 合约代码目录
│ └── demo # 合约子目录
├── target # 编译输出目录
│ ├── deploy
│ │ └── demo-keypair.json # Program Account 私钥
│ │ └── demo.so # 合约二进制文件
│ ├── idl # IDL 文件, 描述合约
│ └── types # TypeScript 类型, 方便 ts 代码调用合约
├── tests # 测试目录
│ └── demo.ts # 测试文件
└── migrations # 部署脚本
└── deploy.ts
Anchor.toml
中指定部署网络和钱包:
[provider]
cluster = "devnet"
wallet = "~/.config/solana/id.json"
也可通过命令行指定 RPC:
anchor deploy --provider.cluster https://devnet.solana.rpcpool.com
部署后,查看详情:
solana program show <Program-ID>
anchor test
localnet
,自动启动节点、部署合约并运行测试。 solana-test-validator
,会因端口冲突报错。 .anchor/program-logs
查看日志。 --skip-local-validator
配合手动启动的节点:
anchor test --skip-local-validator
修改代码后:
anchor build
anchor test --skip-local-validator
销毁后 Program ID 无法再次使用,但可回收 SOL, 可以给我们回一回血:
solana program close <Program-ID> --bypass-warning
示例:
solana balance # 500000008.72812742 SOL
solana program close <Program-ID> --bypass-warning # 回收 1.26686616 SOL
solana balance # 500000009.994988561 SOL
注意: 再次部署会报错,必须重新生成 Program ID, 参照上面的步骤。
代码结构很简单
导入依赖
定义并创建 RPC 连接
加载钱包
获取 Program
调用指令
在 tests
目录下创建 mytest.ts
:
import * as anchor from "@coral-xyz/anchor";
import { Program } from "@coral-xyz/anchor";
import { Demo } from "../target/types/demo";
import { Connection, Keypair } from "@solana/web3.js";
import * as fs from "fs";
// 本地节点 RPC
const RPC_URL = "http://127.0.0.1:8899";
const connection = new Connection(RPC_URL, "confirmed");
// 加载钱包
const walletKeypair = Keypair.fromSecretKey(
new Uint8Array(JSON.parse(fs.readFileSync("/Users/yc/.config/solana/id.json", "utf-8")))
);
const wallet = new anchor.Wallet(walletKeypair);
const provider = new anchor.AnchorProvider(connection, wallet, { preflightCommitment: "confirmed" });
anchor.setProvider(provider);
// 获取 Program
const program = anchor.workspace.demo as Program<Demo>;
async function main() {
console.log("Using wallet:", wallet.publicKey.toBase58());
try {
const tx = await program.methods
.initialize()
.accounts({ signer: wallet.publicKey })
.signers([walletKeypair])
.rpc();
console.log("Transaction Signature:", tx);
} catch (error) {
console.error("Transaction failed:", error);
}
}
main();
当前项目安装 ts-node
(若未安装):
npm install --save-dev ts-node
运行:
npx ts-node tests/mytest.ts
explorer 是支持 localnet 的
之前的 PDA 例子 我在 GitHub 提供代码,我本地的版本为:
anchor-cli 0.31.0
solana-cli 2.1.17
说明: 调用代码中可能遇到编译错误,暂时需用 as any
规避, 这一点坑了大概 2 个小时, 可能是新版的问题:
const txId = await program.methods
.setFavorites(favoriteNumber, favoriteColor)
.accounts({
user: userKeypair.publicKey,
fav: favoritesPda,
systemProgram: SystemProgram.programId,
} as any) // 这里
.signers([userKeypair])
.rpc();
solana-test-validator
和 anchor test
快速验证。 @solana/web3.js
,轻松与合约交互。 赶快动手试试吧!有问题欢迎留言讨论。
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!