Sui.

Beitrag

Teile dein Wissen.

article banner.
0xduckmove.
May 30, 2025
Artikel

BCS-Codierung in Sui: Was es ist und warum es wichtig ist

Wenn Sie auf Sui aufbauen oder an Move herumbasteln, haben Sie wahrscheinlich den Begriff BCS gehört. Das ist die Abkürzung für Binary Canonical Serialization, die ursprünglich für die Diem-Blockchain entwickelt wurde und heute ein Eckpfeiler von Move-basierten Ökosystemen wie Sui, Aptos, Starcoin und 0L ist.

Also ja, du solltest es dir besser gemütlich machen, wenn du ernsthaft daran denkst, in diesem Raum zu bauen.

Was ist BCS?

Binary Canonical Serialization (BCS) ist ein Format, das zum Serialisieren (Codieren) und Deserialisieren (Dekodieren) strukturierter Daten in Byte verwendet wird.

Sie werden sehen, dass es verwendet wird, wenn:

  • Verschlüsselung von Transaktionen vor dem Signieren.
  • Ausgeben oder Analysieren von Ereignissen aus der Blockchain.
  • Interagieren mit Move Smart Contracts außerhalb der Kette über JavaScript.

BCS enthält jedoch keine Typinformationen in den Bytes. Das bedeutet, dass Sie bei der Dekodierung die Struktur im Voraus kennen müssen, im Gegensatz zu Formaten wie JSON oder Protocol Buffers, die eher selbstbeschreibend sind.

Hauptmerkmale von BCS

Metadaten ohne Typ

Die serialisierte Ausgabe enthält keine Hinweise darauf, um welche Typen es sich bei den Feldern handelt. Sie müssen wissen, womit Sie es zu tun haben, wenn Sie dekodieren.

Auftragsabhängige Serialisierung

Strukturen werden in der exakten Reihenfolge ihrer Felder kodiert. Wenn Sie die Reihenfolge ändern, wird Ihre Deserialisierung unterbrochen. Aus diesem Grund müssen die peel_*-Funktionen in Move 1:1 dem Layout der Struktur entsprechen.

Generischer Typ

In einer Struktur wie:

struct BCSObject<T> has drop, copy {
    id: ID,
    owner: address,
    meta: Metadata,
    generic: T
}

Sie können nur bis zum Metafeld zuverlässig deserialisieren. Generische Typen bringen das BCS-Parsen durcheinander. Setzen Sie sie also immer an die letzte Stelle, wenn Sie möchten, dass Ihre Daten sicher dekodiert werden.

Verwenden von BCS in JavaScript

Dank der @mysten /bcs-Bibliothek können Sie mit BCS in JS wie ein Profi arbeiten.

npm i @mysten/bcs

und einfaches Beispiel:

import { BCS, getSuiMoveConfig } from "@mysten/bcs";
const bcs = new BCS(getSuiMoveConfig());

const ser = bcs.ser(BCS.U16, 10);
console.log(ser.toBytes()); // [0x0a, 0x00]

const des = bcs.de(BCS.U16, ser.toBytes());
console.log(des); // 10

Sie können auch Vektoren und Zeichenketten serialisieren:

bcs.ser("vector<u8>", [1, 2, 3, 4]); // 04 01 02 03 04
bcs.ser(BCS.STRING, "test string"); // 0b7465737420737472696e67

Registrierung benutzerdefinierter Typen

Nehmen wir an, Sie haben die folgenden Move-Strukturen:

struct Metadata has drop, copy {
    name: std::ascii::String
}

struct BCSObject has drop, copy {
    id: ID,
    owner: address,
    meta: Metadata
}


Sie können sie so in JS registrieren:

bcs.registerStructType("Metadata", {
  name: BCS.STRING,
});

bcs.registerStructType("BCSObject", {
  id: BCS.ADDRESS,
  owner: BCS.ADDRESS,
  meta: "Metadata",
});

Beispiel für Serialisierung und Deserialisierung

JavaScript-Serialisierung:

const bytes = bcs
  .ser("BCSObject", {
    id: "0x0000000000000000000000000000000000000005",
    owner: "0x000000000000000000000000000000000000000a",
    meta: { name: "aaa" }
  })
  .toString("hex");

console.log("Hex:", bytes);

Die Ausgabe vielleicht:

0x0000000000000000000000000000000000000005000000000000000000000000000000000000000a03616161

Dies kann jetzt in einen Move-Vertrag umgewandelt oder sogar manuell in Sui CLI getestet werden.

BCS mag auf niedriger Ebene und bytelastig aussehen, aber wenn Sie erst einmal verstanden haben, wie es Daten kodiert, werden Sie ein tieferes Verständnis dafür gewinnen, wie Move-Smart-Contracts wirklich funktionieren — und wie Sie On-Chain ↔ Off-Chain-Systeme sicher verbinden können.

Und wenn Sie BCS-Bytes im Sui Explorer debuggen (wie im Folgenden):

BCS-Kodierung Binary Canonical Serialization, oder BCS, ist ein Serialisierungsformat, das im Kontext der Diem-Blockchain entwickelt wurde und heute in den meisten auf Move basierenden Blockchains (Sui, Starcoin, Aptos, 0L) ausgiebig verwendet wird. BCS wird nicht nur in der Move-VM verwendet, sondern auch bei der Transaktions- und Ereigniscodierung, z. B. beim Serialisieren von Transaktionen vor dem Signieren oder beim Analysieren von Ereignisdaten.

Zu wissen, wie BCS funktioniert, ist entscheidend, wenn Sie die Funktionsweise von Move auf einer tieferen Ebene verstehen und ein Move-Experte werden möchten. Lass uns eintauchen.

BCS-Spezifikation und Eigenschaften Es gibt einige allgemeine Eigenschaften der BCS-Codierung, die Sie im weiteren Verlauf der Lektion unbedingt berücksichtigen sollten:

BCS ist ein Datenserialisierungsformat, bei dem die resultierenden Ausgabebytes keine Typinformationen enthalten. Aus diesem Grund muss die Seite, die die kodierten Bytes empfängt, wissen, wie die Daten deserialisiert werden

In BCS gibt es keine Strukturen (da es keine Typen gibt); die Struktur definiert lediglich die Reihenfolge, in der Felder serialisiert werden

Wrapper-Typen werden ignoriert, sodass OuterType und UnnestedType dieselbe BCS-Repräsentation haben:

struct outerType { Besitzer: InnerType } struktur innerType { Adresse: Adresse } struktur UnnestedType { Adresse: Adresse } Typen, die generische Typfelder enthalten, können bis zum ersten generischen Typfeld analysiert werden. Es empfiehlt sich daher, die generischen Typfelder an die letzte Stelle zu setzen, wenn es sich um einen benutzerdefinierten Typ handelt, der sert/de'd wird.

struct BCSObject hat drop, copy { id: ID, Besitzer: Adresse, meta: Metadaten, generisch: T } In diesem Beispiel können wir alles bis zum Metafeld deserialisieren.

Primitive Typen wie Ganzzahlen ohne Vorzeichen sind im Little-Endian-Format kodiert

Der Vektor wird als ULEB128-Länge (mit einer maximalen Länge von bis zu u32) serialisiert, gefolgt vom Inhalt des Vektors.

Die vollständige BCS-Spezifikation finden Sie im BCS-Repository.

Verwendung der @mysten /bcs JavaScript-Bibliothek Installation Die Bibliothek, die Sie für diesen Teil installieren müssen, ist die @mysten /bcs-Bibliothek. Sie können sie installieren, indem Sie in das Stammverzeichnis eines Node-Projekts Folgendes eingeben:

npm i @mysten /bcs Grundlegendes Beispiel Lassen Sie uns zunächst die JavaScript-Bibliothek verwenden, um einige einfache Datentypen zu serialisieren und zu deserialisieren:

importiere {BCS, getSUIMoveConfig} aus "@mysten /bcs „;

//initialisiere den Serializer mit den Standardkonfigurationen von Sui Move const bcs = neues BCS (getSuiMoveConfig ());

//Definiere einige Testdatentypen konstante Ganzzahl = 10; const array = [1, 2, 3, 4]; const string = „Testzeichenfolge“

//benutze bcs.ser () um Daten zu serialisieren const ser_integer = bcs.ser (BCS.U16, integer); const ser_array = bcs.ser („Vektor „, Array); const ser_string = bcs.ser (BCS.STRING, Zeichenfolge);

//benutze bcs.de () um Daten zu deserialisieren const de_integer = bcs.de (BCS.U16, ser_Integer.toBytes ()); const de_array = bcs.de („Vektor „, ser_Array.toBytes ()); const de_string = bcs.de (BCS.STRING, ser_String.toBytes ()); Wir können die Serializer-Instanz mit der integrierten Standardeinstellung für Sui Move initialisieren, indem wir die obige Syntax verwenden, new BCS (getsuiMoveConfig ()).

Es gibt eingebaute ENUMs, die für Sui Move-Typen wie BCS.U16, BCS.STRING usw. verwendet werden können. Für generische Typen kann es mit derselben Syntax wie in Sui Move definiert werden, wie Vector im obigen Beispiel.

Schauen wir uns die serialisierten und deserialisierten Felder genauer an:

Ints sind Little-Endian-Hexadezimalzahlen

0a00 10

das erste Element eines Vektors gibt die Gesamtlänge an,

dann ist es einfach das, was auch immer die Elemente im Vektor sind

0401020304 1,2,3,4 #-Strings sind nur Vektoren von u8, wobei das erste Element der Länge der Zeichenfolge entspricht 0b7465737420737472696e67 Zeichenfolge testen Geben Sie Registrierung ein Wir können die benutzerdefinierten Typen, mit denen wir arbeiten werden, mithilfe der folgenden Syntax registrieren:

importiere {BCS, getsUIMoveConfig} aus "@mysten /bcs „; const bcs = neues BCS (getSUIMoveConfig ());

//Registriere den Metadatentyp bcs.registerStructType („Metadaten“, { Name: BCS.STRING, });

//Das Gleiche gilt für das Hauptobjekt, das wir lesen wollen bcs.registerStructType („bcsObject“, { //BCS.ADDRESS wird sowohl für ID-Typen als auch für Adresstypen verwendet id: BCS.ADDRESS, Besitzer: BCS.ADDRESS, meta: „Metadaten“, }); Verwendung von BCS in Sui Smart Contracts Lassen Sie uns unser Beispiel von oben mit den Strukturen fortsetzen.

Definition der Struktur Wir beginnen mit den entsprechenden Strukturdefinitionen im Sui Move-Vertrag.

{ //.. struct Metadata hat drop, copy { Name: std: :ascii: :Zeichenfolge }

struct BCSObject hat drop, copy { id: ID, Besitzer: Adresse, meta: Metadaten } //.. } Deserialisierung Schreiben wir nun die Funktion zum Deserialisieren eines Objekts in einem Sui-Vertrag.

öffentlicher Spaß object_from_bytes (bcs_bytes: vector): BcsObject {

//Initialisiert die BCS-Byte-Instanz let bcs = bcs: :new (bcs_bytes);

//Verwende peel_*Funktionen, um Werte aus den serialisierten Bytes zu entfernen. //Die Reihenfolge muss dieselbe sein, die wir bei der Serialisierung verwendet haben! let (id, owner, meta) = ( bcs: :peel_address (&mute bcs), bcs: :peel_address (&bcs stummschalten), bcs: :peel_vec_u8 (&mute bcs) ); //Packen Sie eine BCSObject-Struktur mit den Ergebnissen der Serialisierung BCSObject {id: object: :id_from_address (id), owner, meta: Metadata {name: std: :ascii: :string (meta)}} Die verschiedenen peel_*-Methoden im Sui Frame bcs-Modul werden verwendet, um jedes einzelne Feld aus den serialisierten BCS-Bytes zu „schälen“. Beachten Sie, dass die Reihenfolge, in der die Felder abgezogen werden, exakt der Reihenfolge der Felder in der Strukturdefinition entsprechen muss.

Quiz: Warum sind die Ergebnisse der ersten beiden peel_address-Aufrufe für dasselbe BCS-Objekt nicht dieselben?

Beachten Sie auch, wie wir die Typen mit Hilfsfunktionen von Adresse nach ID und von Vector <8>nach std: :ascii: :string konvertieren.

Quiz: Was würde passieren, wenn BSObject einen UID-Typ anstelle eines ID-Typs hätte?

Vollständiges Ser/De-Beispiel Die vollständigen Beispielcodes für JavaScript und Sui Move finden Sie im Ordner example_projects.

Zuerst serialisieren wir ein Testobjekt mit dem JavaScript-Programm:

//Wir konstruieren ein Testobjekt zum Serialisieren. Beachten Sie, dass wir das Format der Ausgabe in Hex angeben können let _bytes = bcs .ser („bcsobject“, { id: „0x000000000000000000000000000000000005", Besitzer: „0x00000000000000000000000000000000000a“, meta: {Name: „aaa"} }) .toString („hexadezimal“); Wir möchten, dass die Ausgabe des BCS-Writers diesmal im Hexadezimalformat vorliegt, das wie oben angegeben werden kann.

Fügen Sie dem Hexstring des Serialisierungsergebnisses das Präfix 0x hinzu und exportieren Sie es in eine Umgebungsvariable:

export Object_HexString=0x00000000000000000000000000000000000000000000000000000000000000000a03616161 Jetzt können wir entweder die zugehörigen Move-Unit-Tests ausführen, um die Richtigkeit zu überprüfen:

Sui Move-Test Du solltest das in der Konsole sehen:

GEBÄUDE bcs_move Move-Komponententests ausführen [PASS] 0x0: :bcs_object: :test_deserialization Testergebnis: OK. Gesamtzahl der Tests: 1; bestanden: 1; nicht bestanden: 0 Oder wir können das Modul veröffentlichen (und die PACKAGE_ID exportieren) und die Methode emit_object mit dem obigen serialisierten BCS-Hexstring aufrufen:

sui client call --function emit_object --module bcs_object --package $PACKAGE_ID --args $OBJECT_HEXSTRING Wir können dann im Sui Explorer auf der Registerkarte Ereignisse der Transaktion nachschauen, ob wir das korrekt deserialisierte BCSObject ausgegeben haben:

  • Sui
  • SDKs and Developer Tools
2
Teilen
Kommentare
.
harry phan.
May 30 2025, 17:12

Was sind Little-Endian und Big-Endian?

Sui is a Layer 1 protocol blockchain designed as the first internet-scale programmable blockchain platform.

610Beiträge1335Antworten
Sui.X.Peera.

Verdiene deinen Anteil an 1000 Sui

Sammle Reputationspunkte und erhalte Belohnungen für deine Hilfe beim Wachstum der Sui-Community.

BelohnungskampagneJuli