Đọ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.

Base Account Type
#[derive(PartialEq, Eq, Clone, Default)]
pub struct Account {
/// lamports in the account
pub 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 rent
pub rent_epoch: Epoch,
}

AccountsAccounts

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:

  1. Tạo một keypair mới (cặp khóa công khai/riêng tư).
  2. Yêu cầu airdrop SOL để cấp vốn cho địa chỉ mới.
  3. 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.

Fetch Account
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 account
const 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));
Console
Click to execute the code.

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.

Example Output
{
"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.

Example Output
{
"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.

Example Output
{
"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.

Example Output
{
"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.

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.

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.

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.

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.

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.

Example Output
{
"data": {
"type": "Buffer",
"data": []
},
"executable": false,
"lamports": 1000000000,
"owner": "11111111111111111111111111111111",
"rentEpoch": 0,
"space": 0
}

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.

Fetch Program Account
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);
Console
Click to execute the code.

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.

Token Program Account
{
"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.

Token Program Account
{
"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.

Token Program Account
{
"data": {
"type": "Buffer",
"data": [127, "...truncated, total bytes: 134080...", 0]
},
"executable": true,
"lamports": 4522329612,
"owner": "BPFLoader2111111111111111111111111111111111",
"rentEpoch": 18446744073709552000,
"space": 134080
}

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.

Đố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.

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.

Token Program Account
{
"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.

Fetch Program Account
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);
Console
Click to execute the code.

Đ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.

Mint Account
{
"data": {
"type": "Buffer",
"data": [1, "...truncated, total bytes: 82...", 103]
},
"executable": false,
"lamports": 407438077149,
"owner": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
"rentEpoch": 18446744073709552000,
"space": 82
}

Trường executablefalse 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.

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.

Mint Account
{
"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.

Mint Account
{
"data": {
"type": "Buffer",
"data": [1, "...truncated, total bytes: 82...", 103]
},
"executable": false,
"lamports": 407438077149,
"owner": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
"rentEpoch": 18446744073709552000,
"space": 82
}

Đ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.

Trường executablefalse 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.

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.

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.

Mint Account
{
"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.

Deserialize Mint Account Data
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");
Console
Click to execute the code.
Mint Account Type
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 initialized
pub 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.

Mint Account
{
"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).

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.

Mint Account
{
"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).

Deserialized Mint Data
{
"address": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
"mintAuthority": "BJE5MMbqXjVwjAF7oxwPYXnTXDyspzZyt4vwenNw5ruG",
"supply": "8985397351591790",
"decimals": 6,
"isInitialized": true,
"freezeAuthority": "7dGbd2QZcCKcTndnHcTL8q7SMVXAkp688NTQYwrRCrar",
"tlvData": {
"type": "Buffer",
"data": []
}
}

Is this page helpful?

Mục lục

Chỉnh sửa trang