> ## Documentation Index
> Fetch the complete documentation index at: https://www.helius.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Cách sử dụng getAccountInfo

> Tìm hiểu các trường hợp sử dụng getAccountInfo, ví dụ mã, tham số yêu cầu, cấu trúc phản hồi và mẹo.

Phương thức RPC [`getAccountInfo`](https://www.helius.dev/docs/api-reference/rpc/http/getaccountinfo) là một công cụ cơ bản để truy vấn blockchain Solana. Phương thức này cho phép bạn truy xuất toàn bộ thông tin được lưu trữ liên kết với một khóa công khai cụ thể của tài khoản. Thông tin này bao gồm số dư lamport của tài khoản, chương trình sở hữu tài khoản, tài khoản có thể thực thi hay không và dữ liệu được lưu trữ trong tài khoản.

## Các trường hợp sử dụng phổ biến

* **Kiểm tra số dư SOL:** Xác định số dư SOL gốc của bất kỳ tài khoản nào.
* **Xác minh sự tồn tại của tài khoản:** Kiểm tra xem tài khoản có khóa công khai đã cho đã được khởi tạo hay chưa (tức là có lamport hoặc dữ liệu).
* **Kiểm tra tài khoản chương trình:** Truy xuất dữ liệu được lưu trữ trong tài khoản do một chương trình sở hữu. Điều này rất quan trọng để hiểu trạng thái của chương trình.
* **Xác định chủ sở hữu tài khoản:** Tìm chương trình sở hữu một tài khoản. Điều này giúp xác định cách diễn giải dữ liệu của tài khoản hoặc liệu tài khoản có thuộc sở hữu của hệ thống hay không.
* **Kiểm tra tài khoản có thể thực thi hay không:** Xác định xem tài khoản có chứa một chương trình đã triển khai hay không.

## Tham số

1. `publicKey` (chuỗi, bắt buộc): Khóa công khai được mã hóa base-58 của tài khoản cần truy vấn.

2. `config` (đối tượng, không bắt buộc): Một đối tượng cấu hình có các trường sau:
   * `commitment` (chuỗi, không bắt buộc): Chỉ định [mức cam kết](https://www.helius.dev/blog/solana-commitment-levels) dùng cho truy vấn. Giá trị mặc định là `finalized`.
     * `finalized`: Nút sẽ truy vấn khối gần đây nhất được đại đa số cụm xác nhận là đã đạt mức khóa tối đa.
     * `confirmed`: Nút sẽ truy vấn khối gần đây nhất đã được đại đa số cụm bỏ phiếu.
     * `processed`: Nút sẽ truy vấn khối gần đây nhất của nút đó. Lưu ý rằng khối có thể chưa hoàn chỉnh.
   * `encoding` (chuỗi, không bắt buộc): Kiểu mã hóa cho dữ liệu tài khoản. Giá trị mặc định là `base64`.
     * `base58` (chậm)
     * `base64`
     * `base64+zstd` (nếu dữ liệu được nén)
     * `jsonParsed`: Nếu dữ liệu tài khoản là trạng thái của một chương trình đã biết (ví dụ: tài khoản token, tài khoản stake), nút sẽ cố gắng phân tích dữ liệu đó thành cấu trúc JSON. Đối với tài khoản chương trình thông thường, định dạng thường được chuyển về dạng nhị phân (base64).
   * `dataSlice` (đối tượng, không bắt buộc): Giới hạn dữ liệu tài khoản được trả về thành một phần cụ thể. Chỉ khả dụng với các kiểu mã hóa `base58`, `base64` hoặc `base64+zstd`.
     * `offset` (số): Số byte tính từ đầu dữ liệu tài khoản để bắt đầu phần cắt.
     * `length` (số): Số byte cần trả về.
   * `minContextSlot` (số, không bắt buộc): Slot tối thiểu mà tại đó yêu cầu có thể được đánh giá.

## Phản hồi

Nếu tìm thấy tài khoản, trường `result` sẽ chứa một đối tượng có hai thuộc tính chính:

* `context` (đối tượng): Chứa siêu dữ liệu về yêu cầu.
  * `slot` (số): Slot nơi thông tin được truy xuất.
  * `apiVersion` (chuỗi, không bắt buộc): Phiên bản API RPC.

* `value` (đối tượng | null): Nếu tài khoản không tồn tại, giá trị này sẽ là `null`. Nếu không, đây là một đối tượng chứa:
  * `lamports` (số): Số lamport (1 SOL = 1.000.000.000 lamport) thuộc sở hữu của tài khoản.
  * `owner` (chuỗi): Khóa công khai được mã hóa base-58 của chương trình sở hữu tài khoản này.
  * `data` (mảng | đối tượng | chuỗi): Dữ liệu được lưu trữ trong tài khoản. Định dạng phụ thuộc vào tham số `encoding` được dùng trong yêu cầu.
    * Đối với `base64` (mặc định), `base58`, `base64+zstd`: Đây thường là một mảng `[encoded_string, encoding_format]`, ví dụ: `["string_data", "base64"]`.
    * Đối với `jsonParsed`: Đây có thể là một đối tượng JSON nếu nút RPC có thể phân tích dữ liệu (ví dụ: đối với tài khoản SPL Token). Nếu không, giá trị có thể mặc định là `["", "base64"]` hoặc tương tự nếu dữ liệu không được nhận dạng là một bố cục tiêu chuẩn.
  * `executable` (boolean): `true` nếu tài khoản chứa một chương trình, nếu không sẽ là `false`.
  * `rentEpoch` (số): Epoch tiếp theo mà tài khoản này sẽ phải trả phí thuê.
  * `space` (số, không bắt buộc): Độ dài dữ liệu tính bằng byte. (Lưu ý: Tài liệu Solana chính thức liệt kê `space` và một số nhà cung cấp RPC có thể cung cấp trường này. Trường này biểu thị tổng dung lượng được phân bổ cho dữ liệu của tài khoản). Để biết thêm thông tin về [dữ liệu tài khoản và quá trình giải tuần tự hóa](https://www.helius.dev/blog/solana-dev-101-deserializing-account-data-on-solana), hãy tham khảo hướng dẫn chi tiết của chúng tôi.

Nếu không tìm thấy tài khoản, trường `value` trong kết quả sẽ là `null`.

## Ví dụ: Truy xuất thông tin tài khoản

Hãy truy xuất thông tin về ID Serum Program V3 (`9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin`) trên mainnet.

**Lưu ý:** Thay `YOUR_API_KEY` bằng khóa API Helius thực tế của bạn trong các ví dụ dưới đây.

<CodeGroup>
  ```bash curl theme={"system"}
  curl https://mainnet.helius-rpc.com/?api-key=YOUR_API_KEY -X POST -H "Content-Type: application/json" -d \
  '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "getAccountInfo",
    "params": [
      "9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin",
      {
        "encoding": "jsonParsed"
      }
    ]
  }'
  ```

  ```javascript JavaScript (using @solana/web3.js) theme={"system"}
  const { Connection, PublicKey } = require('@solana/web3.js');

  async function getAccountDetails() {
    const rpcUrl = 'https://mainnet.helius-rpc.com/?api-key=YOUR_API_KEY'; // Replace YOUR_API_KEY
    const connection = new Connection(rpcUrl, 'confirmed');
    const accountPubKey = new PublicKey('9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin');

    try {
      const accountInfo = await connection.getAccountInfo(accountPubKey);

      if (accountInfo === null) {
        console.log('Account not found.');
        return;
      }

      console.log('Account Info:');
      console.log(`   Lamports: ${accountInfo.lamports}`);
      console.log(`   Owner: ${accountInfo.owner.toBase58()}`);
      console.log(`   Executable: ${accountInfo.executable}`);
      console.log(`   Rent Epoch: ${accountInfo.rentEpoch}`);
      // Data is a Buffer, you might need to deserialize it based on the account type
      // console.log(`   Data: ${accountInfo.data.toString()}`); 
    } catch (error) {
      console.error('Error fetching account info:', error);
    }
  }

  getAccountDetails();
  ```

  ```typescript Kit theme={"system"}
  import { address, createSolanaRpc } from "@solana/kit";

  const rpc_url = "https://mainnet.helius-rpc.com/?api-key=YOUR_API_KEY";
  const rpc = createSolanaRpc(rpc_url);

  const publicKey = address("vines1vzrYbzLMRdu58ou5XTby4qAqVRLmqo36NKPTg");
  const accountInfo = await rpc.getAccountInfo(publicKey).send();

  console.log("Account Info:", accountInfo);
  ```

  ```rust Rust theme={"system"}
  use solana_client::nonblocking::rpc_client::RpcClient;
  use solana_sdk::{commitment_config::CommitmentConfig, pubkey::Pubkey};
  use anyhow::Result;
  use std::str::FromStr;

  #[tokio::main]
  async fn main() -> Result<()> {
      let client = RpcClient::new_with_commitment(
          String::from("https://mainnet.helius-rpc.com/?api-key=YOUR_API_KEY"),
          CommitmentConfig::confirmed()
      );
      let pubkey = Pubkey::from_str("vines1vzrYbzLMRdu58ou5XTby4qAqVRLmqo36NKPTg")?;
      let account = client.get_account(&pubkey).await?;

      println!("{:#?}", account);

      Ok(())
  }
  ```
</CodeGroup>

## Mẹo dành cho nhà phát triển

* **Hiệu suất:** Đối với các ứng dụng cần thường xuyên kiểm tra nhiều tài khoản, hãy cân nhắc sử dụng `getMultipleAccounts` để xử lý yêu cầu theo lô và giảm số lượt trao đổi.
* **Giải tuần tự hóa dữ liệu:** Trường `data` thường cần được giải tuần tự hóa dựa trên cấu trúc dữ liệu của chương trình sở hữu. Bạn thường cần các công cụ và thư viện dành riêng cho chương trình đó (ví dụ: thư viện SPL Token cho tài khoản token). Bài viết blog của chúng tôi về [giải tuần tự hóa dữ liệu tài khoản](https://www.helius.dev/blog/solana-dev-101-deserializing-account-data-on-solana) cung cấp các kỹ thuật và ví dụ hữu ích.
* **Giới hạn tốc độ:** Hãy lưu ý giới hạn tốc độ của nút RPC, đặc biệt khi truy vấn số lượng lớn tài khoản hoặc gửi yêu cầu thường xuyên.
* **Quản lý chi phí:** `getAccountInfo` thường là một truy vấn có chi phí thấp, nhưng việc thăm dò thường xuyên có thể làm chi phí tăng lên. Hãy tối ưu hóa mẫu truy vấn của bạn.
* **Sử dụng `jsonParsed` một cách hợp lý:** Mặc dù `jsonParsed` có thể tiện lợi, nhưng tùy chọn này có thể không hỗ trợ tất cả loại tài khoản và đầu ra có thể thay đổi nếu chương trình cập nhật cấu trúc dữ liệu. Đối với các ứng dụng quan trọng, việc phân tích dữ liệu nhị phân theo một bố cục đã biết sẽ ổn định hơn.
* **Cân nhắc `dataSlice`:** Nếu bạn chỉ cần một phần nhỏ dữ liệu của tài khoản, hãy sử dụng `dataSlice` để giảm lượng dữ liệu được truyền và có thể giảm chi phí truy vấn.

## Các phương thức liên quan

<CardGroup cols={2}>
  <Card title="getMultipleAccounts" href="/docs/vi/api-reference/rpc/http/getmultipleaccounts">
    Truy xuất hàng loạt nhiều tài khoản trong một yêu cầu để cải thiện hiệu suất
  </Card>

  <Card title="getBalance" href="/docs/vi/api-reference/rpc/http/getbalance">
    Chỉ lấy số dư SOL mà không cần đầy đủ thông tin chi tiết về tài khoản
  </Card>
</CardGroup>
