Đọc dữ liệu từ mạng

Đọc dữ liệu từ mạng Solana bằng cách truy xuất các tài khoản khác nhau. Hướng dẫn này giải thích cấu trúc của các tài khoản Solana. Mỗi tài khoản Solana có một địa chỉ duy nhất được dùng để xác định vị trí dữ liệu onchain của tài khoản đó. Tài khoản Solana chứa dữ liệu trạng thái hoặc chương trình thực thi được.

Lấy tài khoản ví

Tài khoản ví là tài khoản thuộc sở hữu của System Program. Tài khoản ví chủ yếu được dùng để lưu trữ SOL và ký các giao dịch. Khi SOL được gửi đến một địa chỉ mới lần đầu tiên, một tài khoản hệ thống sẽ tự động được tạo ra.

Ví dụ dưới đây tạo một Kit client, tạo ra một signer mới, yêu cầu SOL để nạp tiền vào địa chỉ mới, và truy xuất dữ liệu tài khoản từ RPC API của client.

Fetch account
import { createClient, generateKeyPairSigner, lamports } from "@solana/kit";
import { solanaRpc, rpcAirdrop } from "@solana/kit-plugin-rpc";
import { generatedPayer } from "@solana/kit-plugin-signer";
const client = await createClient()
.use(generatedPayer())
.use(
solanaRpc({
rpcUrl: "http://localhost:8899",
rpcSubscriptionsUrl: "ws://localhost:8900"
})
)
.use(rpcAirdrop());
const signer = await generateKeyPairSigner();
console.log(`Address: ${signer.address}`);
// Funding an address with SOL automatically creates an account
await client.airdrop(signer.address, lamports(1_000_000_000n));
const accountInfo = await client.rpc.getAccountInfo(signer.address).send();
console.log(accountInfo);
Console
Click to execute the code.

Khi bạn truy xuất một tài khoản ví bằng getAccountInfo(), Kit trả về phản hồi RPC như trong ví dụ đầu ra ở bên phải.

Phản hồi có hai trường cấp cao nhất: context mô tả thời điểm việc đọc xảy ra, và value chứa các trường tài khoản được trả về bởi phương thức RPC.

Example output
{
context: {
slot: 420602714n,
apiVersion: "3.1.6"
},
value: {
lamports: 1000000000n,
data: ["", "base64"],
owner: "11111111111111111111111111111111",
executable: false,
rentEpoch: 0n,
space: 0n
}
}

Trường context hiển thị slot được dùng để đọc tài khoản và phiên bản RPC API đã phục vụ phản hồi. Một lần đọc sau đó có thể trả về một slot hoặc phiên bản API khác.

Example output
{
context: {
slot: 420602714n,
apiVersion: "3.1.6"
},
value: {
lamports: 1000000000n,
data: ["", "base64"],
owner: "11111111111111111111111111111111",
executable: false,
rentEpoch: 0n,
space: 0n
}
}

Trường value chứa trạng thái tài khoản được trả về bởi phương thức RPC. Các bước sau đây sẽ hướng dẫn qua các trường bên trong value theo thứ tự các trường xuất hiện.

Example output
{
context: {
slot: 420602714n,
apiVersion: "3.1.6"
},
value: {
lamports: 1000000000n,
data: ["", "base64"],
owner: "11111111111111111111111111111111",
executable: false,
rentEpoch: 0n,
space: 0n
}
}

Trường lamports chứa số dư SOL của tài khoản, được đo bằng lamports, đơn vị nhỏ nhất của SOL.

Example output
{
context: {
slot: 420602714n,
apiVersion: "3.1.6"
},
value: {
lamports: 1000000000n,
data: ["", "base64"],
owner: "11111111111111111111111111111111",
executable: false,
rentEpoch: 0n,
space: 0n
}
}

Trường data chứa dữ liệu của tài khoản được lưu trữ dưới dạng byte. RPC trả về dữ liệu tài khoản dưới dạng một tuple: chuỗi dữ liệu đã mã hóa, theo sau là kiểu mã hóa. Đối với các tài khoản ví, chuỗi dữ liệu đã mã hóa là rỗng vì tài khoản lưu trữ 0 byte dữ liệu.

Example output
{
context: {
slot: 420602714n,
apiVersion: "3.1.6"
},
value: {
lamports: 1000000000n,
data: ["", "base64"],
owner: "11111111111111111111111111111111",
executable: false,
rentEpoch: 0n,
space: 0n
}
}

Trường owner cho biết chương trình sở hữu tài khoản. Đối với các ví, chủ sở hữu luôn là System Program, với địa chỉ 11111111111111111111111111111111.

Example output
{
context: {
slot: 420602714n,
apiVersion: "3.1.6"
},
value: {
lamports: 1000000000n,
data: ["", "base64"],
owner: "11111111111111111111111111111111",
executable: false,
rentEpoch: 0n,
space: 0n
}
}

Trường executable cho biết liệu địa chỉ của tài khoản có thể được gọi hay không. true có nghĩa là địa chỉ đại diện cho một chương trình có thể xử lý các lệnh. false có nghĩa là tài khoản lưu trữ trạng thái, chẳng hạn như số dư ví hoặc dữ liệu tài khoản, và không được gọi như một chương trình. Các tài khoản ví sử dụng false.

Trường rentEpoch là một trường kế thừa từ cơ chế rent đã bị khai thác. Trường này vẫn được trả về để đảm bảo khả năng tương thích ngược.

Example output
{
context: {
slot: 420602714n,
apiVersion: "3.1.6"
},
value: {
lamports: 1000000000n,
data: ["", "base64"],
owner: "11111111111111111111111111111111",
executable: false,
rentEpoch: 0n,
space: 0n
}
}

Trường space cho biết số byte chứa trong trường data. Trường space được trả về cùng với phản hồi khi lấy tài khoản, nhưng nó không phải là một phần của kiểu dữ liệu tài khoản.

Đối với ví dụ tài khoản ví, trường space là 0 vì trường data chứa 0 byte dữ liệu.

Example output
{
context: {
slot: 420602714n,
apiVersion: "3.1.6"
},
value: {
lamports: 1000000000n,
data: ["", "base64"],
owner: "11111111111111111111111111111111",
executable: false,
rentEpoch: 0n,
space: 0n
}
}

Khi bạn truy xuất một tài khoản ví bằng getAccountInfo(), Kit trả về phản hồi RPC như trong ví dụ đầu ra ở bên phải.

Phản hồi có hai trường cấp cao nhất: context mô tả thời điểm việc đọc xảy ra, và value chứa các trường tài khoản được trả về bởi phương thức RPC.

Trường context hiển thị slot được dùng để đọc tài khoản và phiên bản RPC API đã phục vụ phản hồi. Một lần đọc sau đó có thể trả về một slot hoặc phiên bản API khác.

Trường value chứa trạng thái tài khoản được trả về bởi phương thức RPC. Các bước sau đây sẽ hướng dẫn qua các trường bên trong value theo thứ tự các trường xuất hiện.

Trường lamports chứa số dư SOL của tài khoản, được đo bằng lamports, đơn vị nhỏ nhất của SOL.

Trường data chứa dữ liệu của tài khoản được lưu trữ dưới dạng byte. RPC trả về dữ liệu tài khoản dưới dạng một tuple: chuỗi dữ liệu đã mã hóa, theo sau là kiểu mã hóa. Đối với các tài khoản ví, chuỗi dữ liệu đã mã hóa là rỗng vì tài khoản lưu trữ 0 byte dữ liệu.

Trường owner cho biết chương trình sở hữu tài khoản. Đối với các ví, chủ sở hữu luôn là System Program, với địa chỉ 11111111111111111111111111111111.

Trường executable cho biết liệu địa chỉ của tài khoản có thể được gọi hay không. true có nghĩa là địa chỉ đại diện cho một chương trình có thể xử lý các lệnh. false có nghĩa là tài khoản lưu trữ trạng thái, chẳng hạn như số dư ví hoặc dữ liệu tài khoản, và không được gọi như một chương trình. Các tài khoản ví sử dụng false.

Trường rentEpoch là một trường kế thừa từ cơ chế rent đã bị khai thác. Trường này vẫn được trả về để đảm bảo khả năng tương thích ngược.

Trường space cho biết số byte chứa trong trường data. Trường space được trả về cùng với phản hồi khi lấy tài khoản, nhưng nó không phải là một phần của kiểu dữ liệu tài khoản.

Đối với ví dụ tài khoản ví, trường space là 0 vì trường data chứa 0 byte dữ liệu.

Example output
{
context: {
slot: 420602714n,
apiVersion: "3.1.6"
},
value: {
lamports: 1000000000n,
data: ["", "base64"],
owner: "11111111111111111111111111111111",
executable: false,
rentEpoch: 0n,
space: 0n
}
}

Lấy Token Program

Ví dụ dưới đâ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. Token Program định nghĩa các lệnh để làm việc với token, chẳng hạn như tạo và chuyển token. Các chương trình được gọi để xử lý các lệnh. Trạng thái chương trình, chẳng hạn như dữ liệu token và số dư, được lưu trữ trong các tài khoản riêng biệt do chương trình sở hữu.

Địa chỉ của Token Program là program account trên chuỗi. Để đơn giản, bạn có thể hiểu địa chỉ chương trình chính là chương trình, vì đó là địa chỉ được dùng để gọi nó. Đối với các chương trình có thể nâng cấp, program account lưu trữ siêu dữ liệu và trỏ đến một programdata account riêng biệt chứa mã thực thi đã triển khai. Bạn có thể xem mã nguồn của Token Program và program account trên Solana Explorer.

Fetch program account
import { address, createClient, fetchJsonParsedAccount } from "@solana/kit";
import { solanaRpc } from "@solana/kit-plugin-rpc";
import { generatedPayer } from "@solana/kit-plugin-signer";
const client = await createClient()
.use(generatedPayer())
.use(
solanaRpc({
rpcUrl: "https://api.mainnet.solana.com"
})
);
const tokenProgramAddress = address(
"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"
);
const accountInfo = await client.rpc
.getAccountInfo(tokenProgramAddress, {
encoding: "base64"
})
.send();
console.log(accountInfo);
const parsedAccount = await fetchJsonParsedAccount(
client.rpc,
tokenProgramAddress
);
console.log(parsedAccount);
Console
Click to execute the code.

Token Program là một program account có thể thực thi. Các chương trình có cùng các trường cơ bản như tất cả tài khoản, nhưng có những điểm khác biệt quan trọng.

Ví dụ Token Program sử dụng mã hóa base64 để trả về dữ liệu thô của program account.

Các bước sau đây hướng dẫn qua các trường bên trong value theo thứ tự các trường xuất hiện.

Token program account
{
context: {
apiVersion: "3.1.14",
slot: 420601581n
},
value: {
data: ["AgAAACfxkLHTr5i4znFMROjK3/n4/EXLjl+sQgLv+BENl903", "base64"],
executable: true,
lamports: 2191440n,
owner: "BPFLoaderUpgradeab1e11111111111111111111111",
rentEpoch: 18446744073709551615n,
space: 36n
}
}

Trường data lưu trữ trạng thái program account của BPF Upgradeable Loader. Phần tử tuple đầu tiên chứa toàn bộ dữ liệu tài khoản được mã hóa dưới dạng base64. Phần tử tuple thứ hai xác định kiểu mã hóa. Ở đây, 36 byte bao gồm siêu dữ liệu và địa chỉ của programdata account.

Đối với các chương trình có thể nâng cấp, trạng thái program account trỏ đến programdata account riêng biệt lưu trữ mã thực thi của chương trình.

Token program account
{
context: {
apiVersion: "3.1.14",
slot: 420601581n
},
value: {
data: ["AgAAACfxkLHTr5i4znFMROjK3/n4/EXLjl+sQgLv+BENl903", "base64"],
executable: true,
lamports: 2191440n,
owner: "BPFLoaderUpgradeab1e11111111111111111111111",
rentEpoch: 18446744073709551615n,
space: 36n
}
}

Trường executable được đặt thành true, cho biết rằng địa chỉ của tài khoản có thể được gọi như một chương trình.

Token program account
{
context: {
apiVersion: "3.1.14",
slot: 420601581n
},
value: {
data: ["AgAAACfxkLHTr5i4znFMROjK3/n4/EXLjl+sQgLv+BENl903", "base64"],
executable: true,
lamports: 2191440n,
owner: "BPFLoaderUpgradeab1e11111111111111111111111",
rentEpoch: 18446744073709551615n,
space: 36n
}
}

Trường lamports chứa số dư SOL của program account. Các program account cần đủ lamport để duy trì trạng thái rent-exempt.

Token program account
{
context: {
apiVersion: "3.1.14",
slot: 420601581n
},
value: {
data: ["AgAAACfxkLHTr5i4znFMROjK3/n4/EXLjl+sQgLv+BENl903", "base64"],
executable: true,
lamports: 2191440n,
owner: "BPFLoaderUpgradeab1e11111111111111111111111",
rentEpoch: 18446744073709551615n,
space: 36n
}
}

Mọi program account đều thuộc sở hữu của một chương trình loader. Đối với Token Program account, owner là BPF Upgradeable Loader.

Token program account
{
context: {
apiVersion: "3.1.14",
slot: 420601581n
},
value: {
data: ["AgAAACfxkLHTr5i4znFMROjK3/n4/EXLjl+sQgLv+BENl903", "base64"],
executable: true,
lamports: 2191440n,
owner: "BPFLoaderUpgradeab1e11111111111111111111111",
rentEpoch: 18446744073709551615n,
space: 36n
}
}

Trường rentEpoch là trường kế thừa từ cơ chế rent đã bị ngừng sử dụng. Trường này vẫn được trả về để đảm bảo khả năng tương thích ngược.

Token program account
{
context: {
apiVersion: "3.1.14",
slot: 420601581n
},
value: {
data: ["AgAAACfxkLHTr5i4znFMROjK3/n4/EXLjl+sQgLv+BENl903", "base64"],
executable: true,
lamports: 2191440n,
owner: "BPFLoaderUpgradeab1e11111111111111111111111",
rentEpoch: 18446744073709551615n,
space: 36n
}
}

Trường space hiển thị toàn bộ kích thước dữ liệu của program account tính bằng byte. Giá trị space chỉ là 36 byte vì program account lưu trữ metadata của loader và địa chỉ của ProgramData account, chứ không phải toàn bộ chương trình đã được biên dịch.

Token program account
{
context: {
apiVersion: "3.1.14",
slot: 420601581n
},
value: {
data: ["AgAAACfxkLHTr5i4znFMROjK3/n4/EXLjl+sQgLv+BENl903", "base64"],
executable: true,
lamports: 2191440n,
owner: "BPFLoaderUpgradeab1e11111111111111111111111",
rentEpoch: 18446744073709551615n,
space: 36n
}
}

Phản hồi trước đó trả về trường data của program account dưới dạng một tuple base64. Phản hồi đã được phân tích cú pháp sẽ giải mã các byte đó thành các trường được đặt tên trên đối tượng data. Trường programData chứa địa chỉ của ProgramData account lưu trữ mã chương trình thực thi.

Parsed Token program account
{
executable: true,
lamports: 43712780n,
programAddress: "BPFLoaderUpgradeab1e11111111111111111111111",
space: 36n,
address: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
data: {
programData: "3gvYRKWyXRR9xKWe1ZjPhLY5ZJRN7KDB4rFZFGoJfFk2",
parsedAccountMeta: { program: "bpf-upgradeable-loader", type: "program" }
},
exists: true
}

Token Program là một program account có thể thực thi. Các chương trình có cùng các trường cơ bản như tất cả tài khoản, nhưng có những điểm khác biệt quan trọng.

Ví dụ Token Program sử dụng mã hóa base64 để trả về dữ liệu thô của program account.

Các bước sau đây hướng dẫn qua các trường bên trong value theo thứ tự các trường xuất hiện.

Trường data lưu trữ trạng thái program account của BPF Upgradeable Loader. Phần tử tuple đầu tiên chứa toàn bộ dữ liệu tài khoản được mã hóa dưới dạng base64. Phần tử tuple thứ hai xác định kiểu mã hóa. Ở đây, 36 byte bao gồm siêu dữ liệu và địa chỉ của programdata account.

Đối với các chương trình có thể nâng cấp, trạng thái program account trỏ đến programdata account riêng biệt lưu trữ mã thực thi của chương trình.

Trường executable được đặt thành true, cho biết rằng địa chỉ của tài khoản có thể được gọi như một chương trình.

Trường lamports chứa số dư SOL của program account. Các program account cần đủ lamport để duy trì trạng thái rent-exempt.

Mọi program account đều thuộc sở hữu của một chương trình loader. Đối với Token Program account, owner là BPF Upgradeable Loader.

Trường rentEpoch là trường kế thừa từ cơ chế rent đã bị ngừng sử dụng. Trường này vẫn được trả về để đảm bảo khả năng tương thích ngược.

Trường space hiển thị toàn bộ kích thước dữ liệu của program account tính bằng byte. Giá trị space chỉ là 36 byte vì program account lưu trữ metadata của loader và địa chỉ của ProgramData account, chứ không phải toàn bộ chương trình đã được biên dịch.

Phản hồi trước đó trả về trường data của program account dưới dạng một tuple base64. Phản hồi đã được phân tích cú pháp sẽ giải mã các byte đó thành các trường được đặt tên trên đối tượng data. Trường programData chứa địa chỉ của ProgramData account lưu trữ mã chương trình thực thi.

Token program account
{
context: {
apiVersion: "3.1.14",
slot: 420601581n
},
value: {
data: ["AgAAACfxkLHTr5i4znFMROjK3/n4/EXLjl+sQgLv+BENl903", "base64"],
executable: true,
lamports: 2191440n,
owner: "BPFLoaderUpgradeab1e11111111111111111111111",
rentEpoch: 18446744073709551615n,
space: 36n
}
}

Lấy một mint account

Một mint account là tài khoản thuộc sở hữu của Token Program, lưu trữ siêu dữ liệu toàn cục cho một token cụ thể. Mint account lưu trữ tổng cung của token, số chữ số thập phân, quyền mint và quyền đóng băng. Địa chỉ của mint account xác định duy nhất một token trên mạng Solana.

Ví dụ dưới đây lấy mint account của USD Coin để minh họa cách trạng thái của một chương trình được lưu trữ trong một tài khoản riêng biệt. Số dư và giá trị cung cụ thể có thể khác nhau tùy thuộc vào slot mà RPC node của bạn đọc từ đó.

Fetch mint account
import { address, createClient } from "@solana/kit";
import { solanaRpc } from "@solana/kit-plugin-rpc";
import { generatedPayer } from "@solana/kit-plugin-signer";
const client = await createClient()
.use(generatedPayer())
.use(
solanaRpc({
rpcUrl: "https://api.mainnet.solana.com"
})
);
const mintAddress = address("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v");
const accountInfo = await client.rpc
.getAccountInfo(mintAddress, {
encoding: "base64"
})
.send();
console.log(accountInfo);
Console
Click to execute the code.

Mint account lưu trữ trạng thái, không phải mã thực thi. Mint account thuộc sở hữu của Token Program, bao gồm các lệnh xác định cách tạo và cập nhật mint account.

Các bước sau đây hướng dẫn qua các trường bên trong value theo thứ tự các trường xuất hiện.

Mint account
{
context: {
slot: 325000000n,
apiVersion: "3.1.14"
},
value: {
data: [
"AQAAAJj+huiNm+Lqi8HMpIeLKYjCQPUrhCS/tA7Rot3LXhmbbq9O2SvsHwAGAQEAAABicKqKWcWUBbRShshncubNEm6bil06OFNtN/e0FOi2Zw==",
"base64"
],
executable: false,
lamports: 407438077149n,
owner: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
rentEpoch: 18446744073709551615n,
space: 82n
}
}

Trường data chứa trạng thái tài khoản Mint đã được tuần tự hóa. Phần tử đầu tiên của tuple chứa toàn bộ 82 byte dữ liệu tài khoản được mã hóa dưới dạng base64. Phần tử thứ hai của tuple xác định kiểu mã hóa.

Để đọc từ một mint account, bạn phải giải tuần tự hóa trường data thành kiểu dữ liệu Mint, được trình bày trong ví dụ tiếp theo.

Mint account
{
context: {
slot: 325000000n,
apiVersion: "3.1.14"
},
value: {
data: [
"AQAAAJj+huiNm+Lqi8HMpIeLKYjCQPUrhCS/tA7Rot3LXhmbbq9O2SvsHwAGAQEAAABicKqKWcWUBbRShshncubNEm6bil06OFNtN/e0FOi2Zw==",
"base64"
],
executable: false,
lamports: 407438077149n,
owner: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
rentEpoch: 18446744073709551615n,
space: 82n
}
}

Trường executable cho biết liệu tài khoản có thể được gọi như một chương trình hay không. Mint account lưu trữ trạng thái, vì vậy trường executablefalse.

Mint account
{
context: {
slot: 325000000n,
apiVersion: "3.1.14"
},
value: {
data: [
"AQAAAJj+huiNm+Lqi8HMpIeLKYjCQPUrhCS/tA7Rot3LXhmbbq9O2SvsHwAGAQEAAABicKqKWcWUBbRShshncubNEm6bil06OFNtN/e0FOi2Zw==",
"base64"
],
executable: false,
lamports: 407438077149n,
owner: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
rentEpoch: 18446744073709551615n,
space: 82n
}
}

Trường lamports chứa số dư SOL được giữ bởi mint account. Giá trị lamports là số dư miễn phí tiền thuê của mint account, không phải tổng cung token.

Mint account
{
context: {
slot: 325000000n,
apiVersion: "3.1.14"
},
value: {
data: [
"AQAAAJj+huiNm+Lqi8HMpIeLKYjCQPUrhCS/tA7Rot3LXhmbbq9O2SvsHwAGAQEAAABicKqKWcWUBbRShshncubNEm6bil06OFNtN/e0FOi2Zw==",
"base64"
],
executable: false,
lamports: 407438077149n,
owner: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
rentEpoch: 18446744073709551615n,
space: 82n
}
}

mint account được sở hữu bởi Token Program. Trường data của mint account chỉ có thể được sửa đổi bởi các lệnh của Token Program.

Mint account
{
context: {
slot: 325000000n,
apiVersion: "3.1.14"
},
value: {
data: [
"AQAAAJj+huiNm+Lqi8HMpIeLKYjCQPUrhCS/tA7Rot3LXhmbbq9O2SvsHwAGAQEAAABicKqKWcWUBbRShshncubNEm6bil06OFNtN/e0FOi2Zw==",
"base64"
],
executable: false,
lamports: 407438077149n,
owner: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
rentEpoch: 18446744073709551615n,
space: 82n
}
}

Trường rentEpoch là một trường kế thừa từ cơ chế rent đã bị loại bỏ. Trường này vẫn được trả về để đảm bảo khả năng tương thích ngược.

Mint account
{
context: {
slot: 325000000n,
apiVersion: "3.1.14"
},
value: {
data: [
"AQAAAJj+huiNm+Lqi8HMpIeLKYjCQPUrhCS/tA7Rot3LXhmbbq9O2SvsHwAGAQEAAABicKqKWcWUBbRShshncubNEm6bil06OFNtN/e0FOi2Zw==",
"base64"
],
executable: false,
lamports: 407438077149n,
owner: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
rentEpoch: 18446744073709551615n,
space: 82n
}
}

Trường space cho thấy mint account chứa 82 byte dữ liệu.

Mint account
{
context: {
slot: 325000000n,
apiVersion: "3.1.14"
},
value: {
data: [
"AQAAAJj+huiNm+Lqi8HMpIeLKYjCQPUrhCS/tA7Rot3LXhmbbq9O2SvsHwAGAQEAAABicKqKWcWUBbRShshncubNEm6bil06OFNtN/e0FOi2Zw==",
"base64"
],
executable: false,
lamports: 407438077149n,
owner: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
rentEpoch: 18446744073709551615n,
space: 82n
}
}

Mint account lưu trữ trạng thái, không phải mã thực thi. Mint account thuộc sở hữu của Token Program, bao gồm các lệnh xác định cách tạo và cập nhật mint account.

Các bước sau đây hướng dẫn qua các trường bên trong value theo thứ tự các trường xuất hiện.

Trường data chứa trạng thái tài khoản Mint đã được tuần tự hóa. Phần tử đầu tiên của tuple chứa toàn bộ 82 byte dữ liệu tài khoản được mã hóa dưới dạng base64. Phần tử thứ hai của tuple xác định kiểu mã hóa.

Để đọc từ một mint account, bạn phải giải tuần tự hóa trường data thành kiểu dữ liệu Mint, được trình bày trong ví dụ tiếp theo.

Trường executable cho biết liệu tài khoản có thể được gọi như một chương trình hay không. Mint account lưu trữ trạng thái, vì vậy trường executablefalse.

Trường lamports chứa số dư SOL được giữ bởi mint account. Giá trị lamports là số dư miễn phí tiền thuê của mint account, không phải tổng cung token.

mint account được sở hữu bởi Token Program. Trường data của mint account chỉ có thể được sửa đổi bởi các lệnh của Token Program.

Trường rentEpoch là một trường kế thừa từ cơ chế rent đã bị loại bỏ. Trường này vẫn được trả về để đảm bảo khả năng tương thích ngược.

Trường space cho thấy mint account chứa 82 byte dữ liệu.

Mint account
{
context: {
slot: 325000000n,
apiVersion: "3.1.14"
},
value: {
data: [
"AQAAAJj+huiNm+Lqi8HMpIeLKYjCQPUrhCS/tA7Rot3LXhmbbq9O2SvsHwAGAQEAAABicKqKWcWUBbRShshncubNEm6bil06OFNtN/e0FOi2Zw==",
"base64"
],
executable: false,
lamports: 407438077149n,
owner: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
rentEpoch: 18446744073709551615n,
space: 82n
}
}

Giải mã hóa mint account

Dữ liệu tài khoản được lưu trữ trong trường data ở định dạng đã được tuần tự hóa. Để đọc dữ liệu đó dưới dạng các trường như supply hoặc decimals, hãy giải tuần tự hóa trường data thành kiểu tài khoản được định nghĩa bởi chương trình sở hữu. Hầu hết các chương trình Solana đều cung cấp thư viện client với các hàm trợ giúp cho bước này. Các hàm trợ giúp này trả về dữ liệu tài khoản có cấu trúc, giúp kết quả dễ làm việc hơn.

Ví dụ, thư viện @solana-program/token bao gồm hàm fetchMint() để tải một mint account và giải tuần tự hóa trường data của mint account thành kiểu dữ liệu Mint được định nghĩa bởi Token Program.

Deserialize mint account data
import { address, createClient } from "@solana/kit";
import { solanaRpc } from "@solana/kit-plugin-rpc";
import { generatedPayer } from "@solana/kit-plugin-signer";
import { fetchMint } from "@solana-program/token";
const client = await createClient()
.use(generatedPayer())
.use(
solanaRpc({
rpcUrl: "https://api.mainnet.solana.com"
})
);
const mintAddress = address("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v");
const mint = await fetchMint(client.rpc, mintAddress);
console.log(mint);
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 fetchMint() tải một mint account và giải tuần tự hóa trường data của mint account thành kiểu tài khoản Mint.

Mint account
{
context: {
slot: 325000000n,
apiVersion: "3.1.14"
},
value: {
data: [
"AQAAAJj+huiNm+Lqi8HMpIeLKYjCQPUrhCS/tA7Rot3LXhmbbq9O2SvsHwAGAQEAAABicKqKWcWUBbRShshncubNEm6bil06OFNtN/e0FOi2Zw==",
"base64"
],
executable: false,
lamports: 407438077149n,
owner: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
rentEpoch: 18446744073709551615n,
space: 82n
}
}

Bạn có thể xem dữ liệu đã được giải mã hoàn toàn của mint account trên Solana Explorer.

Decoded mint account
{
address: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
data: {
mintAuthority: {
__option: "Some",
value: "BJE5MMbqXjVwjAF7oxwPYXnTXDyspzZyt4vwenNw5ruG"
},
supply: 8985397351591790n,
decimals: 6,
isInitialized: true,
freezeAuthority: {
__option: "Some",
value: "7dGbd2QZcCKcTndnHcTL8q7SMVXAkp688NTQYwrRCrar"
}
},
executable: false,
lamports: 407438077149n,
programAddress: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
space: 82n
}

Trường address chứa địa chỉ của mint account.

Decoded mint account
{
address: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
data: {
mintAuthority: {
__option: "Some",
value: "BJE5MMbqXjVwjAF7oxwPYXnTXDyspzZyt4vwenNw5ruG"
},
supply: 8985397351591790n,
decimals: 6,
isInitialized: true,
freezeAuthority: {
__option: "Some",
value: "7dGbd2QZcCKcTndnHcTL8q7SMVXAkp688NTQYwrRCrar"
}
},
executable: false,
lamports: 407438077149n,
programAddress: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
space: 82n
}

Trường data chứa trạng thái tài khoản Mint đã được giải mã. Các trường lồng nhau trong data xuất phát từ kiểu tài khoản Mint của Token Program.

Decoded mint account
{
address: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
data: {
mintAuthority: {
__option: "Some",
value: "BJE5MMbqXjVwjAF7oxwPYXnTXDyspzZyt4vwenNw5ruG"
},
supply: 8985397351591790n,
decimals: 6,
isInitialized: true,
freezeAuthority: {
__option: "Some",
value: "7dGbd2QZcCKcTndnHcTL8q7SMVXAkp688NTQYwrRCrar"
}
},
executable: false,
lamports: 407438077149n,
programAddress: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
space: 82n
}

Trường data.mintAuthority cho biết tài khoản duy nhất có thể tạo ra các đơn vị mới của token.

Decoded mint account
{
address: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
data: {
mintAuthority: {
__option: "Some",
value: "BJE5MMbqXjVwjAF7oxwPYXnTXDyspzZyt4vwenNw5ruG"
},
supply: 8985397351591790n,
decimals: 6,
isInitialized: true,
freezeAuthority: {
__option: "Some",
value: "7dGbd2QZcCKcTndnHcTL8q7SMVXAkp688NTQYwrRCrar"
}
},
executable: false,
lamports: 407438077149n,
programAddress: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
space: 82n
}

Trường supply hiển thị tổng số token đã được đúc. Giá trị cung được tính bằng đơn vị nhỏ nhất của token. Để lấy tổng cung theo đơn vị tiêu chuẩn, hãy điều chỉnh giá trị của trường supply theo decimals.

Decoded mint account
{
address: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
data: {
mintAuthority: {
__option: "Some",
value: "BJE5MMbqXjVwjAF7oxwPYXnTXDyspzZyt4vwenNw5ruG"
},
supply: 8985397351591790n,
decimals: 6,
isInitialized: true,
freezeAuthority: {
__option: "Some",
value: "7dGbd2QZcCKcTndnHcTL8q7SMVXAkp688NTQYwrRCrar"
}
},
executable: false,
lamports: 407438077149n,
programAddress: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
space: 82n
}

Trường decimals cho biết số chữ số thập phân của token.

Decoded mint account
{
address: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
data: {
mintAuthority: {
__option: "Some",
value: "BJE5MMbqXjVwjAF7oxwPYXnTXDyspzZyt4vwenNw5ruG"
},
supply: 8985397351591790n,
decimals: 6,
isInitialized: true,
freezeAuthority: {
__option: "Some",
value: "7dGbd2QZcCKcTndnHcTL8q7SMVXAkp688NTQYwrRCrar"
}
},
executable: false,
lamports: 407438077149n,
programAddress: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
space: 82n
}

Trường isInitialized cho biết liệu mint account đã được khởi tạo hay chưa. Trường isInitialized là một kiểm tra bảo mật được sử dụng trong Token Program.

Decoded mint account
{
address: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
data: {
mintAuthority: {
__option: "Some",
value: "BJE5MMbqXjVwjAF7oxwPYXnTXDyspzZyt4vwenNw5ruG"
},
supply: 8985397351591790n,
decimals: 6,
isInitialized: true,
freezeAuthority: {
__option: "Some",
value: "7dGbd2QZcCKcTndnHcTL8q7SMVXAkp688NTQYwrRCrar"
}
},
executable: false,
lamports: 407438077149n,
programAddress: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
space: 82n
}

Trường data.freezeAuthority hiển thị tài khoản có quyền đóng băng các token account. Một token account là một tài khoản riêng biệt lưu trữ đơn vị token cho chủ sở hữu. Khi bị đóng băng, một token account không thể chuyển hoặc đốt số dư token của nó.

Decoded mint account
{
address: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
data: {
mintAuthority: {
__option: "Some",
value: "BJE5MMbqXjVwjAF7oxwPYXnTXDyspzZyt4vwenNw5ruG"
},
supply: 8985397351591790n,
decimals: 6,
isInitialized: true,
freezeAuthority: {
__option: "Some",
value: "7dGbd2QZcCKcTndnHcTL8q7SMVXAkp688NTQYwrRCrar"
}
},
executable: false,
lamports: 407438077149n,
programAddress: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
space: 82n
}

Trường executable có giá trị false. mint account của USDC lưu trữ trạng thái token, do đó mint account của USDC không thể được gọi như một chương trình.

Decoded mint account
{
address: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
data: {
mintAuthority: {
__option: "Some",
value: "BJE5MMbqXjVwjAF7oxwPYXnTXDyspzZyt4vwenNw5ruG"
},
supply: 8985397351591790n,
decimals: 6,
isInitialized: true,
freezeAuthority: {
__option: "Some",
value: "7dGbd2QZcCKcTndnHcTL8q7SMVXAkp688NTQYwrRCrar"
}
},
executable: false,
lamports: 407438077149n,
programAddress: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
space: 82n
}

Trường lamports chứa số dư SOL của mint account. Giá trị lamports là số dư miễn phí rent của mint account, không phải nguồn cung token.

Decoded mint account
{
address: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
data: {
mintAuthority: {
__option: "Some",
value: "BJE5MMbqXjVwjAF7oxwPYXnTXDyspzZyt4vwenNw5ruG"
},
supply: 8985397351591790n,
decimals: 6,
isInitialized: true,
freezeAuthority: {
__option: "Some",
value: "7dGbd2QZcCKcTndnHcTL8q7SMVXAkp688NTQYwrRCrar"
}
},
executable: false,
lamports: 407438077149n,
programAddress: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
space: 82n
}

Trường programAddress hiển thị chương trình sở hữu mint account. Đối với USDC, chương trình sở hữu là Token Program. Chỉ chương trình sở hữu một tài khoản mới có thể sửa đổi trường data thông qua các lệnh đã triển khai của chương trình đó.

Decoded mint account
{
address: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
data: {
mintAuthority: {
__option: "Some",
value: "BJE5MMbqXjVwjAF7oxwPYXnTXDyspzZyt4vwenNw5ruG"
},
supply: 8985397351591790n,
decimals: 6,
isInitialized: true,
freezeAuthority: {
__option: "Some",
value: "7dGbd2QZcCKcTndnHcTL8q7SMVXAkp688NTQYwrRCrar"
}
},
executable: false,
lamports: 407438077149n,
programAddress: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
space: 82n
}

Trường space hiển thị kích thước dữ liệu gốc của mint account tính bằng byte. Tài khoản Mint cơ bản của Token Program có kích thước 82 byte.

Decoded mint account
{
address: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
data: {
mintAuthority: {
__option: "Some",
value: "BJE5MMbqXjVwjAF7oxwPYXnTXDyspzZyt4vwenNw5ruG"
},
supply: 8985397351591790n,
decimals: 6,
isInitialized: true,
freezeAuthority: {
__option: "Some",
value: "7dGbd2QZcCKcTndnHcTL8q7SMVXAkp688NTQYwrRCrar"
}
},
executable: false,
lamports: 407438077149n,
programAddress: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
space: 82n
}

Hàm fetchMint() tải một mint account và giải tuần tự hóa trường data của mint account thành kiểu tài khoản Mint.

Mint account
{
context: {
slot: 325000000n,
apiVersion: "3.1.14"
},
value: {
data: [
"AQAAAJj+huiNm+Lqi8HMpIeLKYjCQPUrhCS/tA7Rot3LXhmbbq9O2SvsHwAGAQEAAABicKqKWcWUBbRShshncubNEm6bil06OFNtN/e0FOi2Zw==",
"base64"
],
executable: false,
lamports: 407438077149n,
owner: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
rentEpoch: 18446744073709551615n,
space: 82n
}
}

Bạn có thể xem dữ liệu đã được giải mã hoàn toàn của mint account trên Solana Explorer.

Trường address chứa địa chỉ của mint account.

Trường data chứa trạng thái tài khoản Mint đã được giải mã. Các trường lồng nhau trong data xuất phát từ kiểu tài khoản Mint của Token Program.

Trường data.mintAuthority cho biết 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 đúc. Giá trị cung được tính bằng đơn vị nhỏ nhất của token. Để lấy tổng cung theo đơn vị tiêu chuẩn, hãy điều chỉnh giá trị của trường supply theo decimals.

Trường decimals cho biết số chữ số thập phân của token.

Trường isInitialized cho biết liệu mint account đã được khởi tạo hay chưa. Trường isInitialized là một kiểm tra bảo mật được sử dụng trong Token Program.

Trường data.freezeAuthority hiển thị tài khoản có quyền đóng băng các token account. Một token account là một tài khoản riêng biệt lưu trữ đơn vị token cho chủ sở hữu. Khi bị đóng băng, một token account không thể chuyển hoặc đốt số dư token của nó.

Trường executable có giá trị false. mint account của USDC lưu trữ trạng thái token, do đó mint account của USDC không thể được gọi như một chương trình.

Trường lamports chứa số dư SOL của mint account. Giá trị lamports là số dư miễn phí rent của mint account, không phải nguồn cung token.

Trường programAddress hiển thị chương trình sở hữu mint account. Đối với USDC, chương trình sở hữu là Token Program. Chỉ chương trình sở hữu một tài khoản mới có thể sửa đổi trường data thông qua các lệnh đã triển khai của chương trình đó.

Trường space hiển thị kích thước dữ liệu gốc của mint account tính bằng byte. Tài khoản Mint cơ bản của Token Program có kích thước 82 byte.

Decoded mint account
{
address: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
data: {
mintAuthority: {
__option: "Some",
value: "BJE5MMbqXjVwjAF7oxwPYXnTXDyspzZyt4vwenNw5ruG"
},
supply: 8985397351591790n,
decimals: 6,
isInitialized: true,
freezeAuthority: {
__option: "Some",
value: "7dGbd2QZcCKcTndnHcTL8q7SMVXAkp688NTQYwrRCrar"
}
},
executable: false,
lamports: 407438077149n,
programAddress: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
space: 82n
}

Đầu ra dạng tuần tự hóa và phi tuần tự hóa

Cả hai ví dụ đều đọc cùng một mint account của USDC. Phản hồi đầu tiên để nguyên trường data ở dạng tuần tự hóa. Để đọc nội dung của mint account, hãy giải mã dữ liệu đó theo kiểu tài khoản được định nghĩa bởi chương trình sở hữu. Đối với một mint account, Token Program định nghĩa kiểu Mint như được hiển thị ở bên phải.

Trước khi giải mã, trường data chứa dữ liệu tài khoản đã được tuần tự hóa.

Serialized mint account
{
context: {
slot: 325000000n,
apiVersion: "3.1.14"
},
value: {
data: [
"AQAAAJj+huiNm+Lqi8HMpIeLKYjCQPUrhCS/tA7Rot3LXhmbbq9O2SvsHwAGAQEAAABicKqKWcWUBbRShshncubNEm6bil06OFNtN/e0FOi2Zw==",
"base64"
],
executable: false,
lamports: 407438077149n,
owner: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
rentEpoch: 18446744073709551615n,
space: 82n
}
}

Sau khi giải mã dữ liệu dưới dạng Mint, trường data chứa các trường tài khoản được đặt tên.

Deserialized mint account
{
address: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
data: {
mintAuthority: {
__option: "Some",
value: "BJE5MMbqXjVwjAF7oxwPYXnTXDyspzZyt4vwenNw5ruG"
},
supply: 8985397351591790n,
decimals: 6,
isInitialized: true,
freezeAuthority: {
__option: "Some",
value: "7dGbd2QZcCKcTndnHcTL8q7SMVXAkp688NTQYwrRCrar"
}
},
executable: false,
lamports: 407438077149n,
programAddress: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
space: 82n
}

Is this page helpful?

Mục lục

Chỉnh sửa trang