Đọc dữ liệu từ mạng lưới
Phần này khám phá cách đọc dữ liệu từ mạng Solana bằng cách truy xuất các tài khoản khác nhau để hiểu cấu trúc của một tài khoản Solana.
Trên Solana, tất cả dữ liệu tồn tại trong "accounts". Bạn có thể xem dữ liệu trên Solana như một cơ sở dữ liệu công khai với một bảng "Accounts" duy nhất, trong đó mỗi mục là một tài khoản với cùng một loại Account cơ bản.
#[derive(PartialEq, Eq, Clone, Default)]pub struct Account {/// lamports in the accountpub lamports: u64,/// data held in this account#[cfg_attr(feature = "serde", serde(with = "serde_bytes"))]pub data: Vec<u8>,/// the program that owns this account. If executable, the program that loads this account.pub owner: Pubkey,/// this account's data contains a loaded program (and is now read-only)pub executable: bool,/// the epoch at which this account will next owe rentpub rent_epoch: Epoch,}
Accounts
Các tài khoản trên Solana có thể lưu trữ "trạng thái" hoặc các chương trình "thực thi". Mỗi tài khoản có một "địa chỉ" (khóa công khai) đóng vai trò là ID duy nhất được sử dụng để định vị dữ liệu tương ứng trên chuỗi.
Tài khoản Solana chứa một trong hai loại:
- Trạng thái: Dữ liệu được đọc và lưu trữ. Ví dụ, thông tin về token, dữ liệu người dùng, hoặc dữ liệu khác được định nghĩa trong một chương trình.
- Chương trình thực thi: Tài khoản chứa mã thực tế của các chương trình Solana. Những tài khoản này lưu trữ các hướng dẫn mà người dùng có thể gọi.
Sự tách biệt giữa mã chương trình và trạng thái chương trình là một tính năng quan trọng của Mô hình tài khoản Solana. Để biết thêm chi tiết, tham khảo trang Mô hình tài khoản Solana.
Truy xuất tài khoản ví
Ví dụ này minh họa cách:
- Tạo một keypair mới (cặp khóa công khai/riêng tư).
- Yêu cầu airdrop SOL để cấp vốn cho địa chỉ mới.
- Truy xuất dữ liệu tài khoản cho địa chỉ đã được cấp vốn.
Trên Solana, việc cấp vốn cho một địa chỉ mới bằng SOL sẽ tự động tạo một tài khoản thuộc sở hữu của System Program. Tất cả các tài khoản "ví" đơn giản chỉ là các tài khoản thuộc sở hữu của System Program chứa SOL và có thể ký các giao dịch.
import { Keypair, Connection, LAMPORTS_PER_SOL } from "@solana/web3.js";const keypair = Keypair.generate();console.log(`Public Key: ${keypair.publicKey}`);const connection = new Connection("http://localhost:8899", "confirmed");// Funding an address with SOL automatically creates an accountconst signature = await connection.requestAirdrop(keypair.publicKey,LAMPORTS_PER_SOL);await connection.confirmTransaction(signature, "confirmed");const accountInfo = await connection.getAccountInfo(keypair.publicKey);console.log(JSON.stringify(accountInfo, null, 2));
Một "ví" trên Solana là một tài khoản thuộc sở hữu của
System Program,
một trong những chương trình tích hợp sẵn của Solana. Tài khoản ví chủ yếu được
sử dụng để lưu trữ SOL (được theo dõi trong trường lamports
) và để ký các giao
dịch.
Khi bạn truy xuất một tài khoản ví, phản hồi bao gồm các trường được hiển thị trong ví dụ đầu ra.
{"data": {"type": "Buffer","data": []},"executable": false,"lamports": 1000000000,"owner": "11111111111111111111111111111111","rentEpoch": 0,"space": 0}
Trường data
chứa dữ liệu của tài khoản được lưu trữ dưới dạng byte.
Đối với tài khoản ví, trường này trống (0 byte). Các tài khoản khác sử dụng trường này để lưu trữ trạng thái chương trình hoặc mã chương trình có thể thực thi.
{"data": {"type": "Buffer","data": []},"executable": false,"lamports": 1000000000,"owner": "11111111111111111111111111111111","rentEpoch": 0,"space": 0}
Trường executable
cho biết liệu trường data
của tài khoản có chứa mã chương
trình có thể thực thi hay không.
Đối với ví và các tài khoản lưu trữ trạng thái chương trình, trường này là
false
.
{"data": {"type": "Buffer","data": []},"executable": false,"lamports": 1000000000,"owner": "11111111111111111111111111111111","rentEpoch": 0,"space": 0}
Trường lamports
chứa số dư SOL của tài khoản, được tính bằng lamport.
Lamport là đơn vị nhỏ nhất của SOL. 1 SOL = 1.000.000.000 lamport.
{"data": {"type": "Buffer","data": []},"executable": false,"lamports": 1000000000,"owner": "11111111111111111111111111111111","rentEpoch": 0,"space": 0}
Trường owner
hiển thị chương trình sở hữu tài khoản.
Đối với ví, chủ sở hữu luôn là System Program, với địa chỉ
11111111111111111111111111111111
.
Trường rentEpoch
là một trường cũ từ cơ chế đã không còn được sử dụng, nơi các
tài khoản bị tính phí "rent" (bằng lamport) để duy trì dữ liệu của chúng trên
mạng.
Trường này hiện không được sử dụng, nhưng vẫn được giữ lại để tương thích ngược.
Trường space
hiển thị số byte trong trường data
. Đây không phải là trường
trong kiểu Account
chính nó, nhưng được bao gồm trong phản hồi.
Trong ví dụ này, trường space
là 0 vì trường data
chứa 0 byte dữ liệu.
Lấy Token Program
Ví dụ này lấy Token Program để minh họa sự khác biệt giữa tài khoản ví và tài khoản chương trình.
Tài khoản chương trình lưu trữ bytecode đã biên dịch cho mã nguồn của Token Program. Bạn có thể xem tài khoản chương trình này trên Solana Explorer.
import { Connection, PublicKey } from "@solana/web3.js";const connection = new Connection("https://api.mainnet-beta.solana.com","confirmed");const address = new PublicKey("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA");const accountInfo = await connection.getAccountInfo(address);
Token Program là một tài khoản chương trình thực thi trên Solana. Giống như tài khoản ví, các chương trình có cùng cấu trúc dữ liệu Account cơ bản, nhưng có những khác biệt quan trọng trong các trường của nó.
Trường executable
được đặt thành true
, cho biết rằng trường data
của tài
khoản này chứa mã chương trình có thể thực thi.
{"data": {"type": "Buffer","data": [127, "...truncated, total bytes: 134080...", 0]},"executable": true,"lamports": 4522329612,"owner": "BPFLoader2111111111111111111111111111111111","rentEpoch": 18446744073709552000,"space": 134080}
Đối với các tài khoản chương trình, trường data
lưu trữ mã thực thi của chương
trình. Ngược lại, các tài khoản ví có trường dữ liệu trống.
Khi bạn triển khai một chương trình Solana, mã thực thi của chương trình được
lưu trữ trong trường data
của một tài khoản.
{"data": {"type": "Buffer","data": [127, "...truncated, total bytes: 134080...", 0]},"executable": true,"lamports": 4522329612,"owner": "BPFLoader2111111111111111111111111111111111","rentEpoch": 18446744073709552000,"space": 134080}
Các tài khoản chương trình có thể thực thi cũng có một chương trình được chỉ
định là owner
của tài khoản.
Tất cả các tài khoản chương trình đều thuộc sở hữu của một chương trình Loader, đây là một loại chương trình tích hợp sẵn sở hữu các tài khoản chương trình có thể thực thi trên Solana.
Đối với Token Program, owner
là chương trình BPFLoader2.
{"data": {"type": "Buffer","data": [127, "...truncated, total bytes: 134080...", 0]},"executable": true,"lamports": 4522329612,"owner": "BPFLoader2111111111111111111111111111111111","rentEpoch": 18446744073709552000,"space": 134080}
Truy xuất mint account
Ví dụ này truy xuất mint account của USD Coin (USDC) để hiển thị cách các chương trình trên Solana lưu trữ trạng thái trong các tài khoản riêng biệt.
Một tài khoản Mint là một tài khoản thuộc sở hữu của Token Program. Nó lưu trữ metadata toàn cục cho một token cụ thể, bao gồm tổng cung, số thập phân và các tài khoản được ủy quyền để tạo hoặc đóng băng token. Địa chỉ của mint account xác định duy nhất một token trên mạng Solana.
import { Connection, PublicKey } from "@solana/web3.js";const connection = new Connection("https://api.mainnet-beta.solana.com","confirmed");const address = new PublicKey("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v");const accountInfo = await connection.getAccountInfo(address);
Điểm quan trọng cần lưu ý trong ví dụ này là tài khoản Mint lưu trữ trạng thái, không phải mã thực thi.
Các mint account được sở hữu bởi Token Program, bao gồm các chỉ thị xác định cách tạo và cập nhật các mint account.
{"data": {"type": "Buffer","data": [1, "...truncated, total bytes: 82...", 103]},"executable": false,"lamports": 407438077149,"owner": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA","rentEpoch": 18446744073709552000,"space": 82}
Trường executable
là false
bởi vì trường data
của mint account lưu trữ
trạng thái, không phải mã thực thi.
Token Program định nghĩa kiểu dữ liệu Mint
, được lưu trữ trong trường data
của mint account.
{"data": {"type": "Buffer","data": [1, "...truncated, total bytes: 82...", 103]},"executable": false,"lamports": 407438077149,"owner": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA","rentEpoch": 18446744073709552000,"space": 82}
Trường data
chứa trạng thái tài khoản Mint
đã được tuần tự hóa, như quyền
mint, tổng cung, số thập phân.
Để đọc từ một mint account, bạn phải giải tuần tự trường data
thành kiểu dữ
liệu Mint
. Điều này sẽ được đề cập trong bước tiếp theo.
{"data": {"type": "Buffer","data": [1, "...truncated, total bytes: 82...", 103]},"executable": false,"lamports": 407438077149,"owner": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA","rentEpoch": 18446744073709552000,"space": 82}
Token Program (TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA
) sở hữu mint
account.
Điều này có nghĩa là trường data
của mint account chỉ có thể được sửa đổi bởi
các chỉ thị được định nghĩa trong Token Program.
{"data": {"type": "Buffer","data": [1, "...truncated, total bytes: 82...", 103]},"executable": false,"lamports": 407438077149,"owner": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA","rentEpoch": 18446744073709552000,"space": 82}
Giải tuần tự Mint Account
Trường data
của một tài khoản Solana chứa các byte thô. Để diễn giải dữ liệu
này một cách có ý nghĩa, bạn phải giải tuần tự nó thành kiểu dữ liệu thích hợp
được định nghĩa bởi chương trình sở hữu tài khoản.
Hầu hết các chương trình Solana cung cấp thư viện client với các hàm trợ giúp trừu tượng hóa quá trình giải tuần tự. Các hàm này chuyển đổi các byte tài khoản thô thành các kiểu dữ liệu có cấu trúc, giúp dễ dàng làm việc với dữ liệu tài khoản.
Ví dụ, @solana/spl-token
bao gồm hàm getMint()
để
giúp giải tuần tự trường data
của mint account thành kiểu dữ liệu
Mint.
import { PublicKey, Connection } from "@solana/web3.js";import { getMint } from "@solana/spl-token";const connection = new Connection("https://api.mainnet-beta.solana.com","confirmed");const address = new PublicKey("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v");const mintData = await getMint(connection, address, "confirmed");
pub struct Mint {/// Optional authority used to mint new tokens. The mint authority may only/// be provided during mint creation. If no mint authority is present/// then the mint has a fixed supply and no further tokens may be/// minted.pub mint_authority: COption<Pubkey>,/// Total supply of tokens.pub supply: u64,/// Number of base 10 digits to the right of the decimal place.pub decimals: u8,/// Is `true` if this structure has been initializedpub is_initialized: bool,/// Optional authority to freeze token accounts.pub freeze_authority: COption<Pubkey>,}
Hàm getMint()
giải tuần tự trường data
của mint account thành kiểu dữ
liệu
Mint
được định nghĩa bởi Token Program.
{"data": {"type": "Buffer","data": [1, "...truncated, total bytes: 82...", 103]},"executable": false,"lamports": 407438077149,"owner": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA","rentEpoch": 18446744073709552000,"space": 82}
Bạn có thể xem dữ liệu Mint Account đã được giải tuần tự đầy đủ trên Solana Explorer.
Trường address
chứa địa chỉ của mint account.
Địa chỉ của mint account được sử dụng để nhận dạng token trên mạng Solana.
Trường mintAuthority
hiển thị quyền được phép tạo token mới.
Đây là tài khoản duy nhất có thể tạo ra các đơn vị mới của token.
Trường supply
hiển thị tổng số token đã được tạo.
Giá trị này được tính bằng đơn vị nhỏ nhất của token. Để có được tổng cung ứng
theo đơn vị tiêu chuẩn, điều chỉnh giá trị của trường supply
theo decimals
.
Trường decimals
hiển thị số vị trí thập phân cho token.
Trường isInitialized
cho biết liệu tài khoản Mint đã được khởi tạo hay chưa.
Trường này là một kiểm tra bảo mật được sử dụng trong Token Program.
Trường freezeAuthority
hiển thị quyền được phép đóng băng các token account.
Một token account bị đóng băng không thể chuyển hoặc đốt token trong tài khoản.
Trường tlvData
chứa dữ liệu bổ sung cho Token Extensions (yêu cầu giải mã
thêm).
Trường này chỉ liên quan đến các tài khoản được tạo bởi Token Extension Program (Token2022).
Is this page helpful?