MỚI: Helius mua lại Light Protocol
cách giải tuần tự hóa dữ liệu tài khoản trên Solana
Blog/Phát triển

Solana Dev 101 - Giải tuần tự hóa dữ liệu tài khoản trên Solana

Trưởng bộ phận Quan hệ Nhà phát triểnHunter Davis trên LinkedIn
Đọc trong 5 phút

Giới thiệu

Việc tương tác với dữ liệu trên Solana có thể khá phức tạp. Dữ liệu tài khoản và giao dịch thường được mã hóa, điều này có lợi cho hiệu suất nhưng lại gây khó khăn cho nhà phát triển.

Solana sử dụng Borsh (Binary Object Representation Serializer for Hashing) để tuần tự hóa dữ liệu, bao gồm cả quá trình tuần tự hóa và giải tuần tự hóa. Một trong những ưu điểm chính của Borsh là tính xác định, đảm bảo cùng một đầu vào luôn tạo ra kết quả tuần tự hóa nhất quán.

Trong hướng dẫn này, chúng ta sẽ tìm hiểu cách giải tuần tự hóa dữ liệu tài khoản từ một tài khoản token và trả về dữ liệu dễ đọc để bạn có thể sử dụng. Bạn sẽ xem một ví dụ đơn giản về cách phân tích thông tin tài khoản thô của một NFT từ địa chỉ mint bằng thư viện Token Program.

Dưới đây là cách chúng ta sẽ chuyển đổi dữ liệu tài khoản thô thành dạng dễ đọc hơn:

Bạn có thể làm theo toàn bộ mã trong hướng dẫn này bằng cách sao chép kho lưu trữ deserialize-account của chúng tôi tại đây.

Điều kiện tiên quyết

Dưới đây là các điều kiện tiên quyết cho hướng dẫn này:

Thiết lập môi trường

Sao chép kho lưu trữ mẫu:

Mã
git clone https://github.com/helius-labs/deserialize-base.git

Chuyển đến thư mục dự án:

Mã
cd deserialize-base

Cài đặt npm:

Mã
npm install

Bây giờ, dự án đã được thiết lập!

Giờ đây, bạn có thể bắt đầu xây dựng quy trình giải tuần tự hóa dữ liệu tài khoản cho một địa chỉ mint cụ thể.

Các bước xây dựng

Thực hiện theo các bước sau:

1. Truy xuất dữ liệu tài khoản

Trong tệp /src/deserialize.ts, hãy nhập các mô-đun cần thiết:

Mã
import { Connection, PublicKey } from "@solana/web3.js";

Sau đó, bạn sẽ dùng các mô-đun này để xác định kết nối với Solana và PublicKey cho mint có dữ liệu mà bạn muốn giải tuần tự hóa.

Bên dưới phần này, bạn sẽ thiết lập hàm chính.

Bạn cũng sẽ thiết lập kết nối Solana bằng URL RPC của Helius và có thể chỉ định mint sẽ được giải tuần tự hóa trong hướng dẫn.

Mã
async function deserializeMint() {
		// CONNECTION TO SOLANA USING HELIUS
    const rpc = 'https://rpc.helius.xyz/?api-key=';
    const connection = new Connection(rpc);
		// MINT THAT WE ARE DESERIALIZING
    const mint = new PublicKey('6MWfAt3S9Xu4ybxxgPm6e4LSwuXfyAwGXd5yfUqpox9K');

}
deserializeMint()

Hãy nhớ thay api-key ở trên bằng khóa API Helius của riêng bạn. Trong hướng dẫn này, bạn cũng có thể thay mint đang dùng bằng một ví dụ của riêng mình.

Tiếp theo, bạn sẽ thiết lập khối try/catch để truy xuất dữ liệu tài khoản thô của mint này:

Mã
try {
    let { data } = (await connection.getAccountInfo(mint)) || {};
    if (!data) {
      return;
    }
    console.log(data);
  } catch {
    return null;
  }

Trong bước trên, bạn đang dùng kết nối để thực hiện lệnh gọi RPC trên Solana cho getAccountInfo. Lệnh gọi này sẽ trả về dữ liệu ban đầu mà bạn cần phân tích thêm.

Nếu không tìm thấy dữ liệu, hàm sẽ trả về null. Nếu có, kết quả tìm kiếm sẽ được in ra terminal.

Bây giờ, bạn có thể chạy ts-node deserialize để xem kết quả.

Bạn sẽ thấy kết quả tương tự như sau:

Mục đích của việc giải tuần tự hóa ở đây là chuyển dữ liệu sang định dạng dễ đọc.

Để làm điều đó, bạn cần xem mã nguồn nhằm tìm bố cục mà chương trình tạo dữ liệu dự kiến sẽ trả về.

2. Thiết lập các kiểu tài khoản

Trong ví dụ này, bạn cần lấy AccountInfo của một mint SPL 6MWfAt3S9Xu4ybxxgPm6e4LSwuXfyAwGXd5yfUqpox9K.

Để làm điều này, bạn cần phân tích các kiểu của dữ liệu mint thô và bố cục bộ đệm được cung cấp trong Solana Program Library. Hiểu cấu trúc của dữ liệu được cung cấp là bước quan trọng để giải tuần tự hóa bất kỳ dữ liệu nào trên Solana.

Hình ảnh trên cho thấy struct RawMint và MintLayout được xác định trong chương trình. Bạn chỉ cần sao chép chúng vào tệp kiểu để sử dụng.

Bây giờ, hãy chuyển đến thư mục ./src/types.

Trong tệp /src/types.ts, hãy thiết lập lệnh import cho các kiểu:

Mã
import { PublicKey } from "@solana/web3.js";
import { u32, u8, struct } from "@solana/buffer-layout";
import { publicKey, u64, bool } from "@solana/buffer-layout-utils";

Thao tác này sẽ xác định định dạng và bố cục mint thô cần thiết để giải tuần tự hóa dữ liệu tài khoản của NFT trong ví dụ này.

Bây giờ, bạn có thể thiết lập interface và bố cục tương tự như trên.

Mã
// Defining RawMint from https://github.com/solana-labs/solana-program-library/blob/48fbb5b7c49ea35848442bba470b89331dea2b2b/token/js/src/state/mint.ts#L31 //
export interface RawMint {
    mintAuthorityOption: 1 | 0;
    mintAuthority: PublicKey;
    supply: bigint;
    decimals: number;
    isInitialized: boolean;
    freezeAuthorityOption: 1 | 0;
    freezeAuthority: PublicKey;
}

// Defining Buffer Layout from https://github.com/solana-labs/solana-program-library/blob/48fbb5b7c49ea35848442bba470b89331dea2b2b/token/js/src/state/mint.ts#L31 //

/** Buffer layout for de/serializing a mint */
export const MintLayout = struct([
    u32('mintAuthorityOption'),
    publicKey('mintAuthority'),
    u64('supply'),
    u8('decimals'),
    bool('isInitialized'),
    u32('freezeAuthorityOption'),
    publicKey('freezeAuthority'),
]);

Bạn đã thiết lập xong các kiểu cho thông tin tài khoản thô! Bây giờ, bạn có thể import chúng vào tệp deserialize.ts chính và dùng chúng để giải tuần tự hóa dữ liệu đã trả về trước đó.

3. Giải tuần tự hóa dữ liệu trả về

Sau khi hiểu cấu trúc của dữ liệu dự kiến, bạn có thể thiết lập hàm giải mã chỉ bằng một dòng mã. Hãy quay lại tệp src/deserialize.ts để thực hiện bước này.

Trước tiên, trong tệp deserialize.ts chính, hãy import MintLayout từ tệp types.ts:

Mã
import { MintLayout } from "./types";

Bây giờ, bạn chỉ cần thêm một dòng vào hàm giải tuần tự hóa, ngay bên dưới phần truy xuất dữ liệu tài khoản:

Mã
const deserialize = MintLayout.decode(data)
console.log(deserialize)

Đoạn mã này sử dụng MintLayout để giải mã dữ liệu được trả về trong hàm deserializeMint.

Bạn có thể chạy ts-node deserialize từ thư mục ./src và sẽ nhận được kết quả tương tự như sau:

Mã
{
  mintAuthorityOption: 1,
  mintAuthority: PublicKey [PublicKey(5WQAPQ8i8wqHcSWSEkBQ9kqfwRJxxgyZqAtKiwJSW5zT)] {
    _bn:
  },
  supply: 1n,
  decimals: 0,
  isInitialized: true,
  freezeAuthorityOption: 1,
  freezeAuthority: PublicKey [PublicKey(5WQAPQ8i8wqHcSWSEkBQ9kqfwRJxxgyZqAtKiwJSW5zT)] {
    _bn:
  }
}

Kết quả này chắc chắn dễ đọc hơn! Trong bước tiếp theo, bạn có thể trình bày gọn gàng hơn bằng cách phân tách phản hồi theo các kiểu dữ liệu bên trong.

Cuối cùng, bạn vẫn có thể làm sạch dữ liệu bằng cách điều chỉnh phản hồi theo định dạng hiển thị ở trên. Hãy thực hiện như sau:

Mã
// Breaking down the response //
    console.log(deserialize.mintAuthorityOption)
    console.log(deserialize.mintAuthority.toString())
    console.log(deserialize.decimals)
    console.log(deserialize.isInitialized)
    console.log(deserialize.freezeAuthorityOption)
    console.log(deserialize.freezeAuthority.toString())

Trong đoạn mã trên, bạn chỉ cần chuyển đổi PublicKeys được trả về ở định dạng toString. Các dữ liệu khác có thể được trả về theo đúng định dạng nhận được. Vì định dạng dữ liệu đã được xác định trước, chúng ta cũng có thể thiết lập trước và nhận kết quả sau:

Mã
1
5WQAPQ8i8wqHcSWSEkBQ9kqfwRJxxgyZqAtKiwJSW5zT
0
true
1

Bạn có thể điều chỉnh dữ liệu này theo bất kỳ cách nào mình muốn.

Thao tác này chỉ đơn giản là phân tách dữ liệu thành dạng giúp bạn đọc kết quả dễ dàng hơn.

Mã đầy đủ:

Xem mã đầy đủ của deserialize.ts tại đây:

Mã
import { Connection, PublicKey } from "@solana/web3.js";
import { RawMint, MintLayout } from "./types";

async function deserializeMint() {
  const rpc =
    "https://rpc.helius.xyz/?api-key=";
  const connection = new Connection(rpc);
  const mint = new PublicKey("6MWfAt3S9Xu4ybxxgPm6e4LSwuXfyAwGXd5yfUqpox9K");

  try {
    let { data } = (await connection.getAccountInfo(mint)) || {};
    if (!data) {
      return;
    }
		// Data returned.
    console.log(data);
		// Deserialize Data.
    const deserialize = MintLayout.decode(data)

    // Breaking down the response //
    console.log(deserialize.mintAuthorityOption)
    console.log(deserialize.mintAuthority.toString())
    console.log(deserialize.decimals)
    console.log(deserialize.isInitialized)
    console.log(deserialize.freezeAuthorityOption)
    console.log(deserialize.freezeAuthority.toString)

  } catch {
    return null;
  }
}
deserializeMint();

Kết luận

Bạn đã giải tuần tự hóa thành công dữ liệu tài khoản NFT trên Solana! Bạn có thể áp dụng các phương pháp tương tự cho những trường hợp sử dụng khác và nghiên cứu theo cách tương tự để xác định cấu trúc chương trình của dữ liệu cần xử lý.

Hãy nhớ kiểm tra mã nguồn của chương trình chứa dữ liệu mà bạn muốn giải tuần tự hóa và thử áp dụng các phương pháp này để tự thực hiện.

Tài nguyên

‍

Đăng ký nhận tin từ Helius

Luôn cập nhật những thông tin mới nhất về phát triển Solana và nhận thông báo khi chúng tôi đăng bài

Hình ảnh phóng to