
Solana Dev 101 — десериализация данных аккаунта в Solana
Введение
Работать с данными в Solana может быть непросто. Данные аккаунтов и транзакций часто закодированы. Это повышает эффективность, но усложняет работу разработчиков.
Solana использует Borsh (Binary Object Representation Serializer for Hashing) для сериализации и десериализации данных. Одно из ключевых преимуществ Borsh — детерминированность: одинаковые входные данные всегда дают одинаковый сериализованный результат.
В этом руководстве мы разберем, как десериализовать данные токен-аккаунта и получить читаемые данные для дальнейшей работы. В простом примере вы разберете необработанные данные аккаунта NFT по адресу выпуска с помощью библиотеки Token Program.
Ниже показано, как мы преобразуем необработанные данные аккаунта в более читаемый вид:
Чтобы работать с полным кодом из этого руководства, клонируйте наш репозиторий deserialize-account здесь.
Требования
Для этого руководства вам понадобятся:
- Базовые знания TypeScript
- Установленный ts-node
- RPC
- Репозиторий с примером
Настройка окружения
Клонируйте репозиторий с примером:
git clone https://github.com/helius-labs/deserialize-base.gitПерейдите в каталог проекта:
cd deserialize-baseУстановите npm:
npm installТеперь проект настроен!
Можно переходить к реализации десериализации данных аккаунта для указанного адреса выпуска.
Этапы реализации
Выполните следующие шаги:
1. Получите данные аккаунта
Импортируем необходимые модули в файл /src/deserialize.ts:
import { Connection, PublicKey } from "@solana/web3.js";Позже вы используете их, чтобы настроить подключение к Solana, а PublicKey — чтобы указать выпуск, данные которого нужно десериализовать.
Ниже настройте основную функцию.
Также настройте подключение к Solana через URL Helius RPC и укажите выпуск, данные которого будете десериализовать в этом руководстве.
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()В приведенном выше коде обязательно замените api-key на собственный ключ Helius API. Для этого руководства также можно заменить используемый выпуск собственным примером.
Затем настройте try/catch, чтобы получить необработанные данные аккаунта для этого выпуска:
try {
let { data } = (await connection.getAccountInfo(mint)) || {};
if (!data) {
return;
}
console.log(data);
} catch {
return null;
}На этом шаге вы используете подключение, чтобы выполнить RPC-вызов к Solana для getAccountInfo. В ответ вы получите исходные данные, которые нужно будет разобрать.
Если данные не найдены, функция вернет null. В противном случае результаты поиска появятся в терминале.
Теперь выполните ts-node deserialize, чтобы увидеть результат.
Вы увидите примерно такой результат:
Десериализация нужна, чтобы преобразовать эти данные в читаемый формат.
Для этого разработчику нужно обратиться к исходному коду и найти структуру данных, которую должна возвращать создавшая их программа.
2. Настройте типы аккаунта
В этом примере нужно получить AccountInfo для выпуска SPL 6MWfAt3S9Xu4ybxxgPm6e4LSwuXfyAwGXd5yfUqpox9K.
Для этого необходимо разобрать типы необработанных данных выпуска и структуру буфера из Solana Program Library. Понимание структуры данных — важнейший этап десериализации любых данных в Solana.
На изображении выше показаны определенные программой структура RawMint и MintLayout. Их можно просто скопировать в файл типов.
Теперь перейдите в каталог ./src/types.
В файле /src/types.ts настройте импорт типов:
import { PublicKey } from "@solana/web3.js";
import { u32, u8, struct } from "@solana/buffer-layout";
import { publicKey, u64, bool } from "@solana/buffer-layout-utils";Так вы определите формат и структуру необработанных данных выпуска, необходимые для десериализации данных аккаунта NFT в этом примере.
Теперь можно настроить интерфейс и структуру по аналогии с приведенными выше.
Вы используете импортированные PublicKey, u32, u8, publicKey, u64 и bool.
// 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'),
]);Теперь типы для необработанных данных аккаунта настроены! Импортируйте их в основной файл deserialize.ts и используйте для десериализации полученных ранее данных.
В MintLayout значение RawMint определено как структура. По сути, это связывает настроенный вами интерфейс со структурой, определенной в исходном коде на GitHub.
3. Десериализуйте полученные данные
Теперь вы понимаете структуру ожидаемых данных и можете настроить функцию декодирования, которая состоит всего из одной строки кода. Для этого вернитесь к файлу src/deserialize.ts.
Сначала импортируйте MintLayout из файла types.ts в основной файл deserialize.ts:
import { MintLayout } from "./types";Теперь добавьте одну строку в функцию десериализации сразу после получения данных аккаунта:
const deserialize = MintLayout.decode(data)
console.log(deserialize)Здесь MintLayout используется для декодирования данных, возвращенных функцией deserializeMint.
Выполните ts-node deserialize из папки ./src. Вы получите примерно такой результат:
{
mintAuthorityOption: 1,
mintAuthority: PublicKey [PublicKey(5WQAPQ8i8wqHcSWSEkBQ9kqfwRJxxgyZqAtKiwJSW5zT)] {
_bn:
},
supply: 1n,
decimals: 0,
isInitialized: true,
freezeAuthorityOption: 1,
freezeAuthority: PublicKey [PublicKey(5WQAPQ8i8wqHcSWSEkBQ9kqfwRJxxgyZqAtKiwJSW5zT)] {
_bn:
}
}Теперь данные гораздо проще читать! На следующем шаге можно сделать результат еще аккуратнее, разбив ответ по типам.
Наконец, можно дополнительно очистить данные, приведя ответ к показанному выше виду. Для этого выполните следующее:
// 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())В приведенном выше коде нужно преобразовать только PublicKeys, возвращаемый в формате toString. Остальные данные можно вернуть в исходном формате. Поскольку формат данных известен заранее, можно сразу настроить преобразование и получить следующий результат:
1
5WQAPQ8i8wqHcSWSEkBQ9kqfwRJxxgyZqAtKiwJSW5zT
0
true
1Эти данные можно изменить любым удобным способом.
Такой разбор просто позволяет легче читать результаты.
Полный код:
Ниже приведен полный код deserialize.ts:
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();Заключение
Теперь вы десериализовали данные аккаунта NFT в Solana! Те же методы можно применять в других сценариях, а аналогичный анализ поможет определить структуру программы для конкретных данных.
Обязательно изучите исходный код программы, данные которой хотите десериализовать, и попробуйте самостоятельно применить описанные методы.
Ресурсы
Похожие статьи
Подпишитесь на Helius
Следите за новостями разработки на Solana и получайте уведомления о наших публикациях


