Trong phần trước, bạn đã học cách đọc dữ liệu từ mạng Solana bằng cách truy xuất các tài khoản. Ghi dữ liệu lên mạng Solana yêu cầu một giao dịch. Một giao dịch chứa một hoặc nhiều lệnh, và mỗi lệnh gọi một chương trình.
Các chương trình xác định logic nghiệp vụ cho từng lệnh. Khi bạn gửi một giao dịch, Solana runtime thực thi các lệnh trong giao dịch theo thứ tự. Giao dịch mang tính nguyên tử. Hoặc là mọi lệnh trong giao dịch đều thành công, hoặc toàn bộ giao dịch thất bại.
Các ví dụ trong phần này hướng dẫn cách:
- Chuyển SOL giữa các tài khoản
- Tạo một token mint mới
Chuyển SOL
Ví dụ dưới đây chuyển SOL từ tài khoản này sang tài khoản khác. Chỉ chương trình được chỉ định làm chủ sở hữu của tài khoản mới có thể sửa đổi dữ liệu của tài khoản đó hoặc khấu trừ lamport từ số dư của nó. Các tài khoản ví được sở hữu bởi System Program, vì vậy việc chuyển SOL giữa các tài khoản ví yêu cầu một lệnh gọi đến lệnh transfer của System Program. Tài khoản nguồn cũng phải ký giao dịch.
import { createClient, generateKeyPairSigner, lamports } from "@solana/kit";import { solanaRpc, rpcAirdrop } from "@solana/kit-plugin-rpc";import { generatedPayer, airdropPayer } from "@solana/kit-plugin-signer";import { getTransferSolInstruction } from "@solana-program/system";const client = await createClient().use(generatedPayer()).use(solanaRpc({rpcUrl: "http://localhost:8899",rpcSubscriptionsUrl: "ws://localhost:8900"})).use(rpcAirdrop()).use(airdropPayer(lamports(1_000_000_000n)));const receiver = await generateKeyPairSigner();const transferInstruction = getTransferSolInstruction({source: client.payer,destination: receiver.address,amount: lamports(10_000_000n)});const result = await client.sendTransaction([transferInstruction]);console.log("Transaction Signature:", result.context.signature);const { value: senderBalance } = await client.rpc.getBalance(client.payer.address).send();const { value: receiverBalance } = await client.rpc.getBalance(receiver.address).send();console.log("Sender Balance:", senderBalance);console.log("Receiver Balance:", receiverBalance);
Tạo một client Kit cho validator kiểm thử cục bộ. Đoạn mã này thêm một người ký thanh toán, kết nối đến endpoint RPC cục bộ, bật tính năng airdrop và nạp SOL thử nghiệm vào tài khoản thanh toán để thực hiện giao dịch chuyển tiền.
const client = await createClient().use(generatedPayer()).use(solanaRpc({rpcUrl: "http://localhost:8899",rpcSubscriptionsUrl: "ws://localhost:8900"})).use(rpcAirdrop()).use(airdropPayer(lamports(1_000_000_000n)));
Tạo một người ký cho người nhận. Người gửi là client.payer, được tạo bởi
generatedPayer() và được nạp tiền bởi airdropPayer().
const receiver = await generateKeyPairSigner();
Hàm trợ giúp getTransferSolInstruction() tạo một lệnh System Program. Lệnh này
chuyển SOL từ người ký source đến địa chỉ
destination với số lượng amount
lamport được chỉ định.
const transferInstruction = getTransferSolInstruction({source: client.payer,destination: receiver.address,amount: lamports(10_000_000n)});
Gọi client.sendTransaction() với một mảng các lệnh. Client Kit chuyển đổi các
lệnh thành một giao dịch, ký với những người ký được đính kèm vào các lệnh, gửi
giao dịch và chờ xác nhận.
const result = await client.sendTransaction([transferInstruction]);console.log("Transaction Signature:", result.context.signature);
Sau khi giao dịch được xác nhận, hãy lấy cả hai số dư bằng client.rpc.
const { value: senderBalance } = await client.rpc.getBalance(client.payer.address).send();const { value: receiverBalance } = await client.rpc.getBalance(receiver.address).send();
Tạo một token
Ví dụ bên dưới tạo một mint token mới bằng cách sử dụng Token Extensions Program. Một mint account là tài khoản xác định các cài đặt toàn cục của token, chẳng hạn như số thập phân, nguồn cung, quyền phát hành và quyền đóng băng.
Tạo một mint account yêu cầu hai lệnh:
- Gọi System Program để tạo một tài khoản mới thuộc sở hữu của Token Extensions Program.
- Gọi Token Extensions Program để khởi tạo tài khoản đó như một mint.
import { createClient, generateKeyPairSigner, lamports } from "@solana/kit";import { solanaRpc, rpcAirdrop } from "@solana/kit-plugin-rpc";import { generatedPayer, airdropPayer } from "@solana/kit-plugin-signer";import { getCreateAccountInstruction } from "@solana-program/system";import {fetchMint,getInitializeMintInstruction,getMintSize,TOKEN_2022_PROGRAM_ADDRESS} from "@solana-program/token-2022";const client = await createClient().use(generatedPayer()).use(solanaRpc({rpcUrl: "http://localhost:8899",rpcSubscriptionsUrl: "ws://localhost:8900"})).use(rpcAirdrop()).use(airdropPayer(lamports(1_000_000_000n)));const mint = await generateKeyPairSigner();const space = BigInt(getMintSize());const rent = await client.rpc.getMinimumBalanceForRentExemption(space).send();const createAccountInstruction = getCreateAccountInstruction({payer: client.payer,newAccount: mint,space,lamports: rent,programAddress: TOKEN_2022_PROGRAM_ADDRESS});const initializeMintInstruction = getInitializeMintInstruction({mint: mint.address,decimals: 2,mintAuthority: client.payer.address,freezeAuthority: client.payer.address,tokenProgram: TOKEN_2022_PROGRAM_ADDRESS});const result = await client.sendTransaction([createAccountInstruction,initializeMintInstruction]);console.log("Mint Address:", mint.address);console.log("Transaction Signature:", result.context.signature);const mintAccount = await fetchMint(client.rpc, mint.address);console.log("Mint Account:", mintAccount);
Tạo và nạp tiền cho một Kit client, sau đó tạo một signer để sử dụng làm địa chỉ của mint account mới. Payer của client cấp vốn cho việc tạo tài khoản và trả phí giao dịch.
const client = await createClient().use(generatedPayer()).use(solanaRpc({rpcUrl: "http://localhost:8899",rpcSubscriptionsUrl: "ws://localhost:8900"})).use(rpcAirdrop()).use(airdropPayer(lamports(1_000_000_000n)));const mint = await generateKeyPairSigner();
Tính kích thước mint account theo byte, sau đó thực hiện yêu cầu RPC để tính toán số lamport cần thiết để lưu trữ dữ liệu đó trong tài khoản. Số dư yêu cầu này được gọi là rent.
const space = BigInt(getMintSize());const rent = await client.rpc.getMinimumBalanceForRentExemption(space).send();
Lệnh đầu tiên gọi System Program. Lệnh sử dụng payer để nạp
tiền cho newAccount, phân bổ space
cho mint account, chuyển số lamport miễn rent lamports, và
gán quyền sở hữu cho programAddress.
const createAccountInstruction = getCreateAccountInstruction({payer: client.payer,newAccount: mint,space,lamports: rent,programAddress: TOKEN_2022_PROGRAM_ADDRESS});
Lệnh thứ hai gọi Token Extensions Program. Lệnh khởi tạo địa chỉ
mint với giá trị decimals, một
mintAuthority, một
freezeAuthority, và chỉ định
tokenProgram sở hữu mint account.
const initializeMintInstruction = getInitializeMintInstruction({mint: mint.address,decimals: 2,mintAuthority: client.payer.address,freezeAuthority: client.payer.address,tokenProgram: TOKEN_2022_PROGRAM_ADDRESS});
Gửi cả hai lệnh trong một giao dịch. Lệnh tạo tài khoản phải đến trước lệnh khởi tạo mint vì mint account phải tồn tại trước khi Token Extensions Program có thể ghi dữ liệu mint vào tài khoản.
const result = await client.sendTransaction([createAccountInstruction,initializeMintInstruction]);
Sau khi giao dịch được xác nhận, hãy lấy mint account.
const mintAccount = await fetchMint(client.rpc, mint.address);console.log("Mint Account:", mintAccount);
Is this page helpful?