本篇文章将介绍 Solana 上的一些基本脚本,包括:
此外,涉及智能合约交互的脚本将在后续文章中,结合具体合约示例进行讲解。
本教程使用的依赖和版本如下:
"dependencies": {
"@solana/spl-token": "0.4.9",
"@solana/web3.js": "1.98.0"
}
如果在运行过程中遇到 网络问题,建议使用代理,并安装 proxychains4
。
接下来,我们将逐步实现这些功能! 🚀
创建一个新账户,并且保存在本地。
const web3 = require("@solana/web3.js");
const fs = require("fs");
// 连接到 Solana Devnet
const connection = new web3.Connection(web3.clusterApiUrl("devnet"), "confirmed");
// 保存私钥到本地文件
function saveWalletKey(keypair, filename) {
fs.writeFileSync(filename, JSON.stringify(Array.from(keypair.secretKey)));
}
async function main() {
const walletFile = "id.json";
// 创建一个新的账户
const payer = web3.Keypair.generate();
saveWalletKey(payer, walletFile);
console.log("新账户创建并保存:", payer.publicKey.toBase58());
// 查询新账户的余额
const balance = await connection.getBalance(payer.publicKey);
console.log("账户余额:", balance / web3.LAMPORTS_PER_SOL, "SOL");
}
main().catch(console.error);
加载本地的私钥,并且请求空投后,在转出。
const web3 = require('@solana/web3.js');
const fs = require('fs');
// 连接到 Solana Devnet
const connection = new web3.Connection(web3.clusterApiUrl('devnet'), 'confirmed');
// 从文件加载私钥
function loadWalletKey(filename) {
const secretKey = JSON.parse(fs.readFileSync(filename).toString());
return web3.Keypair.fromSecretKey(new Uint8Array(secretKey));
}
async function main() {
const walletFile = 'id.json';
const sender = loadWalletKey(walletFile);
console.log("已加载现有账户:", sender.publicKey.toBase58());
// 获取账户余额
let balance = await connection.getBalance(sender.publicKey);
console.log("当前余额:", balance / web3.LAMPORTS_PER_SOL, "SOL");
// 请求空投
const airdropSignature = await connection.requestAirdrop(
sender.publicKey,
5 * web3.LAMPORTS_PER_SOL
);
await connection.confirmTransaction(airdropSignature, "confirmed");
// 再次检查余额
balance = await connection.getBalance(sender.publicKey);
console.log("空投后余额:", balance / web3.LAMPORTS_PER_SOL, "SOL");
// 创建收款账户
const recipient = web3.Keypair.generate();
console.log("收款账户地址:", recipient.publicKey.toBase58());
// 构建交易
const transaction = new web3.Transaction().add(
web3.SystemProgram.transfer({
fromPubkey: sender.publicKey,
toPubkey: recipient.publicKey,
lamports: web3.LAMPORTS_PER_SOL / 1000, // 0.001 SOL
})
);
// 发送交易
const signature = await web3.sendAndConfirmTransaction(connection, transaction, [sender]);
console.log("交易成功!交易签名:", signature);
}
main().catch(console.error);
新建一个账户并监听,可以手动转入 SOL,进行测试。
const web3 = require('@solana/web3.js');
const connection = new web3.Connection(web3.clusterApiUrl('devnet'), 'confirmed');
async function main() {
// 创建一个新的账户
const account = web3.Keypair.generate();
console.log('正在监听账户:', account.publicKey.toBase58());
// 监听账户的余额变化
connection.onAccountChange(account.publicKey,(accountInfo)=>{
console.log('账户余额更新为:', accountInfo.lamports / web3.LAMPORTS_PER_SOL, 'SOL');
})
}
main().catch(console.error);
创建一个 SPL Token 和账户对应的 token account,然后铸造并查询余额。
const web3 = require("@solana/web3.js");
const splToken = require("@solana/spl-token");
const fs = require("fs");
const connection = new web3.Connection(
web3.clusterApiUrl("devnet"),
"confirmed"
);
function loadWalletKey(filename) {
const secretKey = JSON.parse(fs.readFileSync(filename).toString());
return web3.Keypair.fromSecretKey(new Uint8Array(secretKey));
}
async function main() {
console.log("🔹 加载本地钱包...");
const keypair = loadWalletKey("id.json");
const payer = keypair;
const mintAuthority = keypair;
const freezeAuthority = keypair;
console.log("✅ 钱包已加载:", payer.publicKey.toBase58());
console.log("\n🔹 正在创建 SPL Token...");
const tokenMint = await splToken.createMint(
connection,
payer,
mintAuthority.publicKey,
freezeAuthority.publicKey,
9
);
console.log("创建新SPLToken", tokenMint.toBase58());
console.log("\n🔹 创建 Token Account...");
const payerTokenAccount = await splToken.createAssociatedTokenAccount(
connection,
payer,
tokenMint,
keypair.publicKey
);
console.log("✅ Token 账户:", payerTokenAccount.toBase58());
const mintAmount = 100 * 1e9; // 100 枚代币(9 位小数)
console.log("\n🔹 铸造代币...");
await splToken.mintTo(
connection,
payer,
tokenMint,
payerTokenAccount,
mintAuthority,
mintAmount
);
console.log(`✅ 成功铸造 ${mintAmount / 1e9} 个代币`);
console.log("\n🔹 查询 Token 账户余额...");
const payerTokenAccountInfo = await splToken.getAccount(
connection,
payerTokenAccount
);
console.log(`✅ Token 余额: ${Number(payerTokenAccountInfo.amount) / 1e9}`);
}
main().catch(console.error);
用创建好的 Token 给一个地址转账,转账前需要获取或者创建接收者的 token account。
const web3 = require("@solana/web3.js");
const splToken = require("@solana/spl-token");
const fs = require("fs");
const connection = new web3.Connection(
web3.clusterApiUrl("devnet"),
"confirmed"
);
function loadWalletKey(filename) {
const secretKey = JSON.parse(fs.readFileSync(filename, "utf8"));
return web3.Keypair.fromSecretKey(new Uint8Array(secretKey));
}
async function main() {
console.log("🔹 加载钱包...");
const from = loadWalletKey("id.json");
console.log("✅ 发送者地址:", from.publicKey.toBase58());
const to = new web3.PublicKey("2asHPY75gaEjvXXBDaVKkZQvA44zdhNdBeuBYCtoq5Rj");
const tokenMint = new web3.PublicKey("3rQBaAAfLxUXddEhqa1dj2gKS53ZdcNKcwYP3Qz3gs7D");
console.log("🔹 获取或创建发送者的 Token 账户...");
const fromTokenAccount = await splToken.getOrCreateAssociatedTokenAccount(
connection,
from,
tokenMint,
from.publicKey
);
console.log("✅ 发送者 Token 账户:", fromTokenAccount.address.toBase58());
console.log("🔹 获取或创建接收者的 Token 账户...");
const toTokenAccount = await splToken.getOrCreateAssociatedTokenAccount(
connection,
from,
tokenMint,
to
);
console.log("✅ 接收者 Token 账户:", toTokenAccount.address.toBase58());
const amount = 1 * 1e9; // 1 代币(假设有 9 位小数)
console.log("🔹 构建转账交易...");
let transferInstruction = splToken.createTransferInstruction(
fromTokenAccount.address, // 发送者的 token 账户
toTokenAccount.address, // 接收者的 token 账户
from.publicKey, // 发送者的公钥
amount, // 发送数量
[],
splToken.TOKEN_PROGRAM_ID
);
let transaction = new web3.Transaction().add(transferInstruction);
console.log("🔹 发送交易...");
let signature = await web3.sendAndConfirmTransaction(connection, transaction, [from]);
console.log("✅ 交易成功,签名:", signature);
}
main().catch(console.error);
运行此脚本后,可以使用上节转 token 的脚本进行测试。
const web3 = require("@solana/web3.js");
const splToken = require("@solana/spl-token");
const connection = new web3.Connection(
web3.clusterApiUrl("devnet"),
"confirmed"
);
// 获取 Token 账户地址
async function getTokenAccount(connection, owner, mint) {
console.log("🔹 正在查询 Token 账户...");
const accounts = await connection.getParsedTokenAccountsByOwner(owner, { mint: mint });
if (accounts.value.length > 0) {
console.log("✅ 找到 Token 账户:", accounts.value[0].pubkey.toBase58());
return accounts.value[0].pubkey;
} else {
console.log("⚠️ 未找到 Token 账户");
return null;
}
}
async function main() {
console.log("🔹 监听 Token 账户余额变化...");
// 账户公钥和 Token Mint 地址
const account = new web3.PublicKey("2asHPY75gaEjvXXBDaVKkZQvA44zdhNdBeuBYCtoq5Rj");
const tokenMint = new web3.PublicKey("3rQBaAAfLxUXddEhqa1dj2gKS53ZdcNKcwYP3Qz3gs7D");
// 查询 Token 账户
const tokenAccount = await getTokenAccount(connection, account, tokenMint);
if (!tokenAccount) {
console.error("❌ 监听失败: 该账户没有关联的 Token 账户");
return;
}
console.log("🔹 开始监听账户:", tokenAccount.toBase58());
// 先获取当前的 Token 余额
let lastBalance = 0;
const accountInfo = await connection.getAccountInfo(tokenAccount);
if (accountInfo && accountInfo.data) {
const decodedData = splToken.AccountLayout.decode(accountInfo.data);
lastBalance = Number(decodedData.amount) / 1e9; // 转换为 9 位精度
console.log(`🔹 初始 Token 余额: ${lastBalance} 个(精度 9 位)`);
}
// 监听 Token 账户余额变化
connection.onAccountChange(tokenAccount, async (accountInfo) => {
// 获取 SPL Token 账户数据并解码
const parsedData = accountInfo.data;
if (parsedData && parsedData.length > 0) {
// 使用 spl-token 的 AccountLayout 解码数据
const decodedData = splToken.AccountLayout.decode(parsedData);
const tokenBalance = Number(decodedData.amount) / 1e9; // 转换为 9 位精度
// 打印余额变化
if (lastBalance !== 0) {
const changeInBalance = tokenBalance - lastBalance;
console.log(`🔄 Token 余额变化: ${changeInBalance} 个(精度 9 位)`);
}
// 更新上一次的余额
lastBalance = tokenBalance;
} else {
console.log("⚠️ 无法解析 Token 账户数据");
}
});
}
main().catch(console.error);
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!