从网络读取数据

通过获取不同的账户,从 Solana 网络读取数据。本节将帮助您了解 Solana 账户 的结构。每个 Solana 账户都有一个唯一的 地址,用于定位其对应的链上数据。账户包含 状态数据或可执行程序

获取钱包账户

钱包是由 System Program 拥有的账户。钱包主要用于持有 SOL 并签署交易。当 SOL 第一次发送到一个新地址时,会自动创建一个系统账户。

下面的示例生成一个 新 keypair请求 SOL 为新的公钥地址提供资金,并检索新资助钱包的账户数据

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.

当您获取一个钱包账户时,响应中会包含右侧示例输出中显示的字段。

data 字段包含账户以字节形式存储的数据。对于钱包账户,此字段为空(0 字节)。

executable 字段表示账户的 data 字段是否包含可执行的程序代码。对于钱包账户,此字段为 false

lamports 字段包含账户的 SOL 余额,单位为 lamports

owner 字段显示拥有该账户的程序。对于钱包账户,所有者始终为 System Program,其地址为 11111111111111111111111111111111

rentEpoch 字段是已弃用 rent 机制的遗留字段。(该字段为兼容旧版本而保留。)

space 字段显示 data 字段中包含的字节数。该字段并非 Account type 本身的字段,但会包含在响应中。

在此示例中,space 字段为 0,因为 data 字段包含 0 字节数据。

当您获取一个钱包账户时,响应中会包含右侧示例输出中显示的字段。

data 字段包含账户以字节形式存储的数据。对于钱包账户,此字段为空(0 字节)。

executable 字段表示账户的 data 字段是否包含可执行的程序代码。对于钱包账户,此字段为 false

lamports 字段包含账户的 SOL 余额,单位为 lamports

owner 字段显示拥有该账户的程序。对于钱包账户,所有者始终为 System Program,其地址为 11111111111111111111111111111111

rentEpoch 字段是已弃用 rent 机制的遗留字段。(该字段为兼容旧版本而保留。)

space 字段显示 data 字段中包含的字节数。该字段并非 Account type 本身的字段,但会包含在响应中。

在此示例中,space 字段为 0,因为 data 字段包含 0 字节数据。

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

获取 Token Program

以下示例获取了 Token Program,以演示钱包账户和程序账户之间的区别。程序账户存储了 Token Program 的 源代码 的已编译字节码。您可以在 Solana Explorer 上查看此程序账户。

Fetch program account
import { Connection, PublicKey } from "@solana/web3.js";
const connection = new Connection(
"https://api.mainnet.solana.com",
"confirmed"
);
const address = new PublicKey("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA");
const accountInfo = await connection.getAccountInfo(address);
Console
Click to execute the code.

Token Program 是一个可执行的程序账户。程序与所有 账户 具有相同的基础字段,但存在关键差异。

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

executable 字段被设置为 true,表示账户的 data 字段包含可执行代码。

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

data 字段存储程序的可执行代码。

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

每个 program account 都由其 loader program 拥有。在此示例中,owner 是 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 是一个可执行的程序账户。程序与所有 账户 具有相同的基础字段,但存在关键差异。

executable 字段被设置为 true,表示账户的 data 字段包含可执行代码。

data 字段存储程序的可执行代码。

每个 program account 都由其 loader program 拥有。在此示例中,owner 是 BPFLoader2 程序。

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

获取 mint account

mint account 是由 Token Program 拥有的账户,用于存储特定代币的全局元数据。这包括总供应量、小数位数,以及被授权铸造或冻结代币的账户。mint account 的地址在 Solana 网络上唯一标识一个代币。

下面的示例获取了 USD Coin 的 mint account,以演示程序的状态如何存储在单独的账户中。

Fetch program account
import { Connection, PublicKey } from "@solana/web3.js";
const connection = new Connection(
"https://api.mainnet.solana.com",
"confirmed"
);
const address = new PublicKey("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v");
const accountInfo = await connection.getAccountInfo(address);
Console
Click to execute the code.

mint account 存储的是状态,而不是可执行代码。它们由 Token Program 拥有,其中包含定义如何创建和更新 mint account 的指令。

mint account 的 data 字段存储的是状态,而不是可执行代码,因此 executable 字段为 false

Token Program 定义了 Mint 数据类型,并将其存储在 data 字段中。

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

data 字段包含序列化后的 Mint 账户状态,例如 mint authority、总供应量、小数位数等。

要读取 Mint account,需要将 data 字段反序列化为 Mint 数据类型,具体见下一个示例

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

mint account 归 Token Program 所有。这意味着其 data 字段只能通过 Token Program 的指令进行修改。

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

mint account 存储的是状态,而不是可执行代码。它们由 Token Program 拥有,其中包含定义如何创建和更新 mint account 的指令。

mint account 的 data 字段存储的是状态,而不是可执行代码,因此 executable 字段为 false

Token Program 定义了 Mint 数据类型,并将其存储在 data 字段中。

data 字段包含序列化后的 Mint 账户状态,例如 mint authority、总供应量、小数位数等。

要读取 Mint account,需要将 data 字段反序列化为 Mint 数据类型,具体见下一个示例

mint account 归 Token Program 所有。这意味着其 data 字段只能通过 Token Program 的指令进行修改。

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

反序列化 Mint 账户

在账户的 data 字段中的原始字节能够被有意义地解释之前,必须先进行反序列化。合适的数据类型由拥有该账户的程序定义。大多数 Solana 程序都提供了客户端库和辅助函数,简化了反序列化过程。这些函数会将原始账户字节转换为结构化数据类型,使账户数据的操作更加便捷。

例如,@solana/spl-token 库中包含了 getMint() 函数,用于帮助将 mint account 的 data 字段反序列化为 Token Program 定义的 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.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>,
}

getMint() 函数会将 mint account 的 data 字段反序列化为 Mint account 类型。

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

您可以在 Solana Explorer 上查看完全反序列化的 mint 账户 数据。

address 字段包含 mint account 的地址。

mintAuthority 字段显示唯一可以创建该 token 新单位的账户。

supply 字段显示已铸造的 token 总数。该值以 token 的最小单位计量。要获得标准单位的总供应量,需要用 decimals 字段调整 supply 字段的值。

decimals 字段表示该 token 的小数位数。

isInitialized 字段表示 mint account 是否已初始化。该字段是 Token Program 中的安全检查。

freezeAuthority 字段显示有权冻结 token account 的账户。被冻结的 token account 无法转账或销毁其所持有的 token。

tlvData 字段包含 Token Extensions 的额外数据,需要进一步反序列化。该字段仅适用于由 Token Extension Program(Token2022)创建的账户。

getMint() 函数会将 mint account 的 data 字段反序列化为 Mint account 类型。

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

您可以在 Solana Explorer 上查看完全反序列化的 mint 账户 数据。

address 字段包含 mint account 的地址。

mintAuthority 字段显示唯一可以创建该 token 新单位的账户。

supply 字段显示已铸造的 token 总数。该值以 token 的最小单位计量。要获得标准单位的总供应量,需要用 decimals 字段调整 supply 字段的值。

decimals 字段表示该 token 的小数位数。

isInitialized 字段表示 mint account 是否已初始化。该字段是 Token Program 中的安全检查。

freezeAuthority 字段显示有权冻结 token account 的账户。被冻结的 token account 无法转账或销毁其所持有的 token。

tlvData 字段包含 Token Extensions 的额外数据,需要进一步反序列化。该字段仅适用于由 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?

Table of Contents

Edit Page

管理者

©️ 2026 Solana 基金会版权所有
取得联系