NEU: Helius übernimmt Light Protocol
Account-Daten auf Solana deserialisieren
Blog/Entwicklung

Solana Dev 101 – Account-Daten auf Solana deserialisieren

Leiter Developer RelationsHunter Davis auf LinkedIn
5 Min. Lesezeit

Einführung

Die Arbeit mit Daten auf Solana kann anspruchsvoll sein. Account- und Transaktionsdaten sind häufig codiert. Das steigert die Effizienz, strapaziert aber die Nerven von Entwicklern.

Solana nutzt Borsh (Binary Object Representation Serializer for Hashing) für die Serialisierung seiner Daten. Dazu gehören sowohl die Serialisierung als auch die Deserialisierung. Ein wesentlicher Vorteil von Borsh ist der Determinismus: Dieselbe Eingabe erzeugt immer dieselbe serialisierte Ausgabe.

In diesem Tutorial lernst du, wie du Account-Daten eines Token-Accounts deserialisierst und in lesbarer Form zurückgibst. Als einfaches Beispiel zerlegst du mit der Token Program Library die rohen Account-Informationen eines NFT anhand seiner Mint-Adresse.

So wandeln wir rohe Account-Daten in ein besser lesbares Format um:

Den vollständigen Code dieses Tutorials findest du, indem du unser deserialize-account-Repository hier klonst.

Voraussetzungen

Für dieses Tutorial brauchst du:

Umgebung einrichten

Klone das Beispiel-Repository:

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

Wechsle in das Projektverzeichnis:

Code
cd deserialize-base

Installiere npm:

Code
npm install

Damit ist dein Projekt eingerichtet!

Jetzt kannst du die Logik erstellen, mit der du die Account-Daten einer bestimmten Mint-Adresse deserialisierst.

Implementierungsschritte

Führe diese Schritte aus:

1. Account-Daten abrufen

Importiere in unserer Datei /src/deserialize.ts die benötigten Module:

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

Damit definierst du später unsere Verbindung zu Solana sowie den PublicKey für die Mint, deren Daten du deserialisieren möchtest.

Darunter richtest du die Hauptfunktion ein.

Außerdem stellst du über unsere Helius RPC-URL eine Verbindung zu Solana her und legst die Mint fest, die du im Tutorial deserialisierst.

Code
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()

Ersetze oben api-key unbedingt durch deinen eigenen Helius API-Schlüssel. Du kannst für dieses Tutorial auch die verwendete Mint durch ein eigenes Beispiel ersetzen.

Richte als Nächstes einen try/catch-Block ein, um die rohen Account-Daten dieser Mint abzurufen:

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

Im obigen Schritt nutzt du unsere Verbindung, um für getAccountInfo einen RPC-Aufruf auf Solana auszuführen. Dadurch erhältst du die Ausgangsdaten, die du anschließend weiter zerlegst.

Wenn keine Daten gefunden werden, gibt die Funktion null zurück. Andernfalls zeigt sie die Suchergebnisse in deinem Terminal an.

Führe jetzt ts-node deserialize aus, um die Ergebnisse zu sehen.

Du solltest ein ähnliches Ergebnis sehen:

Durch die Deserialisierung wandelst du diese Daten in ein lesbares Format um.

Dazu musst du im Quellcode das Layout finden, das von dem Programm vorgegeben wird, welches die Daten erstellt hat.

2. Account-Typen einrichten

In diesem Beispiel möchtest du die AccountInfo für eine SPL-Mint 6MWfAt3S9Xu4ybxxgPm6e4LSwuXfyAwGXd5yfUqpox9K abrufen.

Dazu musst du die Typen für die rohen Mint-Daten und das Buffer-Layout aufschlüsseln, die in der Solana Program Library definiert sind. Die Struktur der jeweiligen Daten zu verstehen, ist ein entscheidender Schritt beim Deserialisieren beliebiger Daten auf Solana.

Das obige Bild zeigt den vom Programm definierten RawMint-Struct und MintLayout. Du kannst beide einfach in unsere Typendatei kopieren und dort verwenden.

Wechsle jetzt in unser Verzeichnis ./src/types.

Richte in der Datei /src/types.ts den Import für unsere Typen ein:

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

Damit definierst du das oben gezeigte Format und Layout der rohen Mint-Daten, die du zum Deserialisieren der Account-Daten des NFT in diesem Beispiel brauchst.

Jetzt kannst du unser Interface und Layout wie oben gezeigt einrichten.

Code
// 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'),
]);

Damit hast du unsere Typen für die rohen Account-Informationen eingerichtet! Importiere sie jetzt in unsere Hauptdatei deserialize.ts und deserialisiere damit die zuvor zurückgegebenen Daten.

3. Zurückgegebene Daten deserialisieren

Da du jetzt die Struktur der erwarteten Daten kennst, kannst du unsere Decode-Funktion einrichten. Dafür brauchst du nur eine einzige Codezeile. Kehre dazu zur Datei src/deserialize.ts zurück.

Importiere zuerst in unserer Hauptdatei deserialize.ts unser MintLayout aus der Datei types.ts:

Code
import { MintLayout } from "./types";

Füge jetzt direkt unter dem Abruf der Account-Daten eine einzelne Zeile zu unserer Deserialisierungsfunktion hinzu:

Code
const deserialize = MintLayout.decode(data)
console.log(deserialize)

Dabei wird unser MintLayout verwendet, um die von unserer Funktion deserializeMint zurückgegebenen Daten zu decodieren.

Führe ts-node deserialize in deinem Ordner ./src aus. Du erhältst ein ähnliches Ergebnis:

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

Das ist deutlich besser lesbar! Im nächsten Schritt kannst du die Antwort anhand der darin enthaltenen Typen aufschlüsseln und übersichtlicher gestalten.

Zum Schluss kannst du die Daten noch bereinigen, indem du die Antwort an das oben gezeigte Format anpasst. Gehe dazu wie folgt vor:

Code
// 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())

Im obigen Code musst du nur den zurückgegebenen PublicKeys in ein toString-Format umwandeln. Alle anderen Daten können in ihrem ursprünglichen Format zurückgegeben werden. Da das Datenformat bekannt ist, können wir dies ebenfalls vorab einrichten. Das Ergebnis sieht dann so aus:

Code
1
5WQAPQ8i8wqHcSWSEkBQ9kqfwRJxxgyZqAtKiwJSW5zT
0
true
1

Du kannst diese Daten beliebig anpassen.

Dabei werden sie lediglich in eine Form zerlegt, in der du die Ergebnisse besser lesen kannst.

Vollständiger Code:

Hier findest du den vollständigen Code für deserialize.ts:

Code
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();

Fazit

Du hast jetzt NFT-Account-Daten auf Solana deserialisiert! Du kannst dieselben Methoden auf andere Anwendungsfälle übertragen und mit ähnlichen Rechercheschritten die Programmstruktur für die jeweiligen Daten ermitteln.

Prüfe immer den Quellcode des Programms, dessen Daten du deserialisieren möchtest. Nutze dann diese Methoden, um die Deserialisierung selbst umzusetzen.

Ressourcen

‍

Helius abonnieren

Bleib bei der Solana-Entwicklung auf dem Laufenden und erhalte Updates, wenn wir neue Beiträge veröffentlichen

Vergrößertes Bild