
Solana Dev 101 — Desserializando dados de conta na Solana
Introdução
Interagir com dados na Solana pode ser desafiador. Os dados de contas e transações costumam ser codificados, o que é bom para a eficiência, mas ruim para a sanidade dos desenvolvedores.
A Solana usa Borsh (Binary Object Representation Serializer for Hashing) para serializar seus dados, incluindo os processos de serialização e desserialização. Uma das principais vantagens do Borsh é seu determinismo, que garante uma saída serializada consistente para a mesma entrada.
Neste tutorial, veremos como desserializar os dados de uma conta de token e retornar dados legíveis que você possa utilizar. Usaremos um exemplo simples para decompor as informações brutas da conta de um NFT com base em seu endereço de mint usando a biblioteca Token Program.
Veja abaixo como transformaremos dados brutos de conta em algo mais legível:
Você pode acompanhar o código completo deste tutorial clonando nosso repositório deserialize-account aqui.
Pré-requisitos
Estes são os pré-requisitos para este tutorial:
- Conhecimentos básicos de TypeScript
- ts-node instalado
- Um RPC
- Repositório de exemplo
Configuração do ambiente
Clone o repositório de exemplo:
git clone https://github.com/helius-labs/deserialize-base.gitAcesse o diretório do projeto:
cd deserialize-baseInstale o npm:
npm installAgora o projeto está configurado!
Você já pode começar a criar a lógica para desserializar os dados da conta de um endereço de mint específico.
Etapas de implementação
Siga estas etapas:
1. Busque os dados da conta
No arquivo /src/deserialize.ts, vamos importar os módulos necessários:
import { Connection, PublicKey } from "@solana/web3.js";Você usará isso mais adiante para definir nossa conexão com a Solana e o PublicKey do mint cujos dados deseja desserializar.
Logo abaixo, você configurará a função principal.
Você também configurará nossa conexão com a Solana usando a URL do RPC da Helius e poderá definir o mint que será desserializado no tutorial.
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()No código acima, substitua api-key pela sua própria chave de API da Helius. Se preferir, você também pode substituir o mint usado por um exemplo próprio neste tutorial.
Em seguida, você configurará um bloco try/catch para buscar os dados brutos da conta desse mint:
try {
let { data } = (await connection.getAccountInfo(mint)) || {};
if (!data) {
return;
}
console.log(data);
} catch {
return null;
}Na etapa acima, você está usando nossa conexão para fazer uma chamada RPC na Solana para getAccountInfo. Isso retornará os dados iniciais que precisam ser decompostos.
Se nenhum dado for encontrado, o retorno será null. Caso contrário, os resultados da busca serão exibidos no terminal.
Agora você pode executar ts-node deserialize para ver os resultados.
Você deverá ver um resultado semelhante ao seguinte:
O objetivo da desserialização aqui é converter esses dados em um formato legível.
Para fazer isso, você precisa consultar o código-fonte e encontrar o layout que o programa responsável pela criação dos dados espera fornecer.
2. Configure os tipos de conta
Neste exemplo, você quer obter o AccountInfo de um mint SPL 6MWfAt3S9Xu4ybxxgPm6e4LSwuXfyAwGXd5yfUqpox9K.
Para isso, você precisará decompor os tipos dos dados brutos do mint e o layout do buffer fornecidos pela Solana Program Library. Entender a estrutura dos dados fornecidos é uma etapa essencial para desserializar qualquer dado na Solana.
A imagem acima mostra a struct RawMint e o MintLayout definidos pelo programa. Você pode simplesmente copiá-los para nosso arquivo de tipos.
Agora, acesse nosso diretório ./src/types.
No arquivo /src/types.ts, configure a importação dos nossos tipos:
import { PublicKey } from "@solana/web3.js";
import { u32, u8, struct } from "@solana/buffer-layout";
import { publicKey, u64, bool } from "@solana/buffer-layout-utils";Isso definirá o formato e o layout brutos do mint necessários para desserializar os dados da conta do NFT neste exemplo.
Agora você pode configurar nossa interface e nosso layout de forma semelhante ao exemplo acima.
Você está usando PublicKey, u32, u8, publicKey, u64 e bool, que foram importados.
// 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'),
]);Agora você configurou nossos tipos para as informações brutas da conta! Já pode importá-los no arquivo principal deserialize.ts e usá-los para desserializar os dados retornados anteriormente.
No MintLayout, o RawMint é definido como a struct. Essencialmente, isso associa a interface que você configurou ao tipo desse layout definido no código-fonte do GitHub.
3. Desserialize os dados retornados
Agora que você entende a estrutura dos dados esperados, pode configurar nossa função de decodificação, que requer apenas uma linha de código. Volte ao arquivo src/deserialize.ts para configurá-la.
Primeiro, no arquivo principal deserialize.ts, importe nosso MintLayout do arquivo types.ts:
import { MintLayout } from "./types";Agora basta adicionar uma única linha à nossa função de desserialização, logo abaixo do trecho em que você busca os dados da conta:
const deserialize = MintLayout.decode(data)
console.log(deserialize)Isso usa nosso MintLayout para decodificar os dados retornados pela função deserializeMint.
Você pode executar ts-node deserialize na pasta ./src e obterá um resultado semelhante ao seguinte:
{
mintAuthorityOption: 1,
mintAuthority: PublicKey [PublicKey(5WQAPQ8i8wqHcSWSEkBQ9kqfwRJxxgyZqAtKiwJSW5zT)] {
_bn:
},
supply: 1n,
decimals: 0,
isInitialized: true,
freezeAuthorityOption: 1,
freezeAuthority: PublicKey [PublicKey(5WQAPQ8i8wqHcSWSEkBQ9kqfwRJxxgyZqAtKiwJSW5zT)] {
_bn:
}
}Agora está muito mais legível! Na próxima etapa, você pode organizar melhor o resultado decompondo a resposta de acordo com os tipos retornados.
Por fim, você ainda pode limpar esses dados ajustando a resposta ao formato mostrado acima. Para isso, faça o seguinte:
// 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())No código acima, você só precisa converter o PublicKeys retornado em um formato toString. Os demais dados podem ser retornados no formato em que foram recebidos. Como o formato dos dados é conhecido, também podemos configurar isso antecipadamente, o que retornará o seguinte:
1
5WQAPQ8i8wqHcSWSEkBQ9kqfwRJxxgyZqAtKiwJSW5zT
0
true
1Você pode ajustar esses dados como preferir.
Isso apenas os decompõe em um formato que facilita a leitura dos resultados.
Código completo:
Veja aqui o código completo de 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();Conclusão
Agora você desserializou os dados da conta de um NFT na Solana! Você pode aplicar os mesmos métodos a outros casos de uso e adotar técnicas de pesquisa semelhantes para descobrir a estrutura do programa responsável pelos dados.
Consulte o código-fonte do programa cujos dados você deseja desserializar e tente aplicar esses métodos por conta própria.
Recursos
Artigos relacionados
Assine a Helius
Acompanhe as novidades mais recentes do desenvolvimento Solana e receba atualizações quando publicarmos


