
Solana Dev 101 - Deserialización de datos de cuentas en Solana
Introducción
Interactuar con datos en Solana puede ser difícil. Los datos de cuentas y transacciones suelen estar codificados, lo cual mejora la eficiencia, pero complica el trabajo de desarrollo.
Solana usa Borsh (serializador de representación binaria de objetos para hashing) para serializar sus datos, lo que incluye tanto la serialización como la deserialización. Una de las principales ventajas de Borsh es su determinismo, que garantiza una salida serializada uniforme para una misma entrada.
En este tutorial, aprenderás a deserializar los datos de una cuenta de tokens y devolverlos en un formato legible que puedas usar. Verás un ejemplo sencillo que desglosa la información sin procesar de la cuenta de un NFT a partir de su dirección de mint mediante la biblioteca Token Program.
A continuación, puedes ver cómo transformaremos los datos sin procesar de una cuenta en algo más legible:
Puedes consultar el código completo de este tutorial clonando nuestro repositorio deserialize-account aquí.
Requisitos previos
Estos son los requisitos previos para este tutorial:
- Conocimientos básicos de TypeScript
- ts-node instalado
- Un RPC
- Repositorio de ejemplo
Configuración del entorno
Clona el repositorio de ejemplo:
git clone https://github.com/helius-labs/deserialize-base.gitVe al directorio del proyecto:
cd deserialize-baseInstala npm:
npm install¡Ya tienes el proyecto configurado!
Ahora puedes comenzar a crear el proceso para deserializar los datos de la cuenta de una dirección de mint determinada.
Pasos para crear la solución
Sigue estos pasos:
1. Obtén los datos de la cuenta
En nuestro archivo /src/deserialize.ts, importemos los módulos necesarios:
import { Connection, PublicKey } from "@solana/web3.js";Más adelante, usarás esto para definir nuestra conexión con Solana y el PublicKey del mint cuyos datos quieres deserializar.
Debajo, configurarás la función principal.
También configurarás nuestra conexión con Solana mediante nuestra URL RPC de Helius y podrás establecer el mint que deserializarás en el 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()Asegúrate de reemplazar api-key con tu propia clave de API de Helius en el código anterior. También puedes reemplazar el mint usado por un ejemplo propio para este tutorial.
A continuación, configurarás un bloque try/catch para obtener los datos sin procesar de la cuenta de este mint:
try {
let { data } = (await connection.getAccountInfo(mint)) || {};
if (!data) {
return;
}
console.log(data);
} catch {
return null;
}En el paso anterior, usas nuestra conexión para hacer una llamada RPC en Solana para getAccountInfo. Esto devolverá los datos iniciales que necesitas desglosar.
Si no se encuentran datos, devolverá null. De lo contrario, mostrará los resultados de la búsqueda en tu terminal.
Ahora puedes ejecutar ts-node deserialize para ver los resultados.
Deberías ver un resultado similar al siguiente:
El objetivo de la deserialización es convertir estos datos en un formato legible.
Para hacerlo, tendrás que consultar el código fuente y encontrar la estructura que espera el programa que creó los datos.
2. Configura los tipos de cuenta
En este ejemplo, quieres obtener AccountInfo para un mint de SPL 6MWfAt3S9Xu4ybxxgPm6e4LSwuXfyAwGXd5yfUqpox9K.
Para hacerlo, tendrás que desglosar los tipos de los datos sin procesar del mint y el diseño del búfer que proporciona la Solana Program Library. Comprender la estructura de los datos proporcionados es un paso esencial para deserializar cualquier dato en Solana.
La imagen anterior muestra el struct RawMint y MintLayout definidos por el programa. Puedes copiarlos directamente a nuestro archivo de tipos para usarlos.
Ahora ve a nuestro directorio ./src/types.
En el archivo /src/types.ts, configura la importación de nuestros tipos:
import { PublicKey } from "@solana/web3.js";
import { u32, u8, struct } from "@solana/buffer-layout";
import { publicKey, u64, bool } from "@solana/buffer-layout-utils";Esto definirá el formato y el diseño de los datos sin procesar del mint necesarios para deserializar los datos de la cuenta del NFT de este ejemplo.
Ahora puedes configurar nuestra interfaz y nuestro diseño de forma similar a lo anterior.
Estás usando los elementos importados PublicKey, u32, u8, publicKey, u64 y 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'),
]);¡Ya configuraste nuestros tipos para la información sin procesar de la cuenta! Ahora puedes importarlos en nuestro archivo principal deserialize.ts y usarlos para deserializar los datos que devolviste antes.
En MintLayout, RawMint se define como el struct. Básicamente, esto asigna la interfaz que configuraste a este diseño definido en el código fuente de GitHub.
3. Deserializa los datos devueltos
Ahora que comprendes la estructura de los datos esperados, puedes configurar nuestra función de decodificación, que requiere una sola línea de código. Vuelve al archivo src/deserialize.ts para configurarla.
Primero, en nuestro archivo principal deserialize.ts, importa MintLayout desde nuestro archivo types.ts:
import { MintLayout } from "./types";Ahora solo tienes que agregar una línea a nuestra función de deserialización, justo debajo de donde obtienes los datos de la cuenta:
const deserialize = MintLayout.decode(data)
console.log(deserialize)Esto usa nuestro MintLayout para decodificar los datos devueltos en nuestra función deserializeMint.
Puedes ejecutar ts-node deserialize desde tu carpeta ./src y obtendrás un resultado similar al siguiente:
{
mintAuthorityOption: 1,
mintAuthority: PublicKey [PublicKey(5WQAPQ8i8wqHcSWSEkBQ9kqfwRJxxgyZqAtKiwJSW5zT)] {
_bn:
},
supply: 1n,
decimals: 0,
isInitialized: true,
freezeAuthorityOption: 1,
freezeAuthority: PublicKey [PublicKey(5WQAPQ8i8wqHcSWSEkBQ9kqfwRJxxgyZqAtKiwJSW5zT)] {
_bn:
}
}¡Esto es mucho más legible! Puedes ordenarlo un poco más si, en el siguiente paso, desglosas la respuesta según sus tipos.
Por último, puedes depurar aún más estos datos ajustando la respuesta para que coincida con lo que se muestra arriba. Puedes hacerlo de la siguiente manera:
// 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())En el código anterior, solo necesitas convertir el valor PublicKeys devuelto en formato toString. Los demás datos pueden devolverse en el formato en que se reciben. Como conocemos el formato esperado de los datos, también podemos configurarlo de antemano, lo que devolverá lo siguiente:
1
5WQAPQ8i8wqHcSWSEkBQ9kqfwRJxxgyZqAtKiwJSW5zT
0
true
1Puedes ajustar estos datos como prefieras.
Esto simplemente los desglosa en un formato que te permite leer mejor los resultados.
Código completo:
Consulta aquí el 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();Conclusión
¡Ya deserializaste datos de la cuenta de un NFT en Solana! Puedes aplicar los mismos métodos a otros casos de uso y usar técnicas de investigación similares para determinar la estructura del programa correspondiente a los datos.
Asegúrate de consultar el código fuente del programa cuyos datos quieres deserializar e intenta aplicar estos métodos por tu cuenta.
Recursos
Artículos relacionados
Suscríbete a Helius
Mantente al día con las novedades del desarrollo en Solana y recibe actualizaciones cuando publiquemos


