Wie schreibe ich einen WebAssembly-Smart-Vertrag im Ontology-Netzwerk? Teil 1: Rost

Wie schreibe ich einen WebAssembly-Smart-Vertrag im Ontology-Netzwerk? Teil 1: Rost

Die Ontology Wasm-Technologie reduziert die Kosten für die Migration intelligenter dApp-Verträge mit komplexer Geschäftslogik in die Blockchain und bereichert so das dApp-Ökosystem erheblich.

Derzeit Ontologie Wasm Unterstützt gleichzeitig die Rust- und C++-Entwicklung. Die Rust-Sprache unterstützt Wasm besser und der generierte Bytecode ist einfacher, wodurch die Kosten für Vertragsaufrufe weiter gesenkt werden können. So, Wie kann man mit Rust einen Vertrag im Ontology-Netzwerk entwickeln?

Entwicklung eines WASM-Vertrags mit Rust

Erstellen Sie einen Vertrag

Kastenwagen ist ein gutes Projekterstellungs- und Paketverwaltungstool für die Rust-Entwicklung, das Entwicklern hilft, die Interaktion von Code und Bibliotheken von Drittanbietern besser zu organisieren. Um einen neuen Ontology Wasm-Vertrag zu erstellen, führen Sie einfach den folgenden Befehl aus:

Wie schreibe ich einen WebAssembly-Smart-Vertrag im Ontology-Netzwerk? Teil 1: Rost

Die dadurch erzeugte Projektstruktur:

Wie schreibe ich einen WebAssembly-Smart-Vertrag im Ontology-Netzwerk? Teil 1: Rost

Die Datei Cargo.toml wird zum Einrichten grundlegender Projektinformationen und abhängiger Bibliotheksinformationen verwendet. Der Abschnitt [lib] der Datei muss auf crate-type = ["cdylib"] gesetzt sein. Die Datei lib.rs wird zum Schreiben des Vertragslogikcodes verwendet. Darüber hinaus müssen Sie Abhängigkeitsparameter zum Abschnitt [dependencies] der Cargo.toml-Konfigurationsdatei hinzufügen:

Wie schreibe ich einen WebAssembly-Smart-Vertrag im Ontology-Netzwerk? Teil 1: Rost

Mit dieser Abhängigkeit können Entwickler Schnittstellen aufrufen, die mit der Ontology-Blockchain und Tools wie dem Serialisierungsparameter interagieren.

Vertragserfassungsfunktion

Jedes Programm hat eine Eingabefunktion, wie die Hauptfunktion, die wir normalerweise sehen, aber der Vertrag hat keine Hauptfunktion. Wenn ein Wasm-Vertrag mit Rust entwickelt wird, wird die Standard-Invoke-Funktion als Eingabefunktion für die Verwendung des Vertrags verwendet. Der Name einer Funktion in Rust wird unklar sein, wenn Rust-Quellcode in Bytecode kompiliert wird, der von einer virtuellen Maschine ausgeführt werden kann. Um zu verhindern, dass der Compiler redundanten Code generiert und die Größe des Vertrags verringert, fügt die Aufruffunktion die Annotation #[no_mangle] hinzu.

Wie erhält die Aufruffunktion Parameter zum Ausführen einer Transaktion?

Die ontio_std-Bibliothek stellt eine runtime::input()-Funktion bereit, um die Parameter zum Ausführen einer Transaktion abzurufen. Entwickler können ZeroCopySource verwenden, um das resultierende Byte-Array zu deserialisieren. Dabei ist das erste gelesene Byte-Array der Name der aufrufenden Methode, gefolgt von den Methodenparametern.

Wie wird das Ergebnis der Vertragsabwicklung zurückgegeben?

Die von der ontio_std-Bibliothek bereitgestellte Funktion runtime::ret gibt das Ergebnis einer Methodenausführung zurück.

Die fertige Aufruffunktion sieht folgendermaßen aus:

Wie schreibe ich einen WebAssembly-Smart-Vertrag im Ontology-Netzwerk? Teil 1: Rost

Vertragsdaten serialisieren und deserialisieren

Bei der Entwicklung von Verträgen stoßen Entwickler immer wieder auf Probleme mit der Serialisierung und Deserialisierung, insbesondere mit der Frage, wie ein Strukturdatentyp in der Datenbank gespeichert wird und wie ein aus der Datenbank gelesenes Byte-Array deserialisiert wird, um einen Strukturdatentyp zu erhalten.

Die ontio_std-Bibliothek stellt Decoder- und Encoderschnittstellen für die Datenserialisierung und -deserialisierung bereit. Die Felder einer Struktur implementieren auch die Decoder- und Encoder-Schnittstellen, sodass die Struktur serialisiert und deserialisiert werden kann. Instanzen der Sink-Klasse sind erforderlich, wenn verschiedene Datentypen serialisiert werden. Eine Instanz der Sink-Klasse verfügt über ein Feld buf vom Set-Typ, das die Daten vom Bytetyp speichert, und alle serialisierten Daten werden in buf gespeichert.

Bei Daten fester Länge (z. B. Byte, u16, u32, u64 usw.) werden die Daten direkt in ein Byte-Array konvertiert und dann in buf gespeichert. Bei Daten mit nicht fester Länge muss zuerst die Länge und dann Ddata serialisiert werden (z. B. vorzeichenlose Ganzzahlen unbekannter Größe, einschließlich u16, u32 oder u64 usw.).

Deserialisierung ist das genaue Gegenteil. Für jede Serialisierungsmethode gibt es eine entsprechende Deserialisierungsmethode. Die Deserialisierung erfordert die Verwendung von Instanzen der Source-Klasse. Diese Klasseninstanz hat zwei Felder buf und pos. Buf dient zum Speichern der zu deserialisierenden Daten und pos zum Speichern der aktuellen Leseposition. Wenn ein bestimmter Datentyp gelesen wird und Sie dessen Länge kennen, können Sie ihn direkt lesen. Bei Daten unbekannter Länge lesen Sie zuerst die Länge und dann den Inhalt.

Greifen Sie auf Daten in der Kette zu und aktualisieren Sie sie

ontology-wasm-cdt-rust - eine Betriebsmethode für die Arbeit mit Daten in der Kette gekapselt, die für Entwickler praktisch ist, um Vorgänge wie das Hinzufügen, Löschen, Ändern und Abfragen von Daten in der Kette wie folgt zu implementieren:

  • Datenbank::get(Schlüssel) – wird verwendet, um Daten aus der Kette anzufordern, und der Schlüssel fordert die Implementierung der AsRef-Schnittstelle an;
  • Datenbank::Put(Schlüssel, Wert) - Wird zum Speichern von Daten im Netzwerk verwendet. Der Schlüssel fordert die Implementierung der AsRef-Schnittstelle an und der Wert fordert die Implementierung der Encoder-Schnittstelle an.
  • Datenbank::delete(Schlüssel) – wird verwendet, um Daten aus der Kette zu entfernen, und der Schlüssel fordert die Implementierung der AsRef-Schnittstelle an.

Vertragsprüfung

Wenn die Methoden eines Vertrags implementiert werden, benötigen wir Zugriff auf die Daten in der Kette und wir benötigen eine geeignete virtuelle Maschine, um den Bytecode des Vertrags auszuführen. Daher ist es im Allgemeinen erforderlich, den Vertrag zum Testen in der Kette bereitzustellen. Diese Testmethode ist jedoch problematisch. Um Entwicklern das Testen von Verträgen zu erleichtern, stellt die Bibliothek ontio_std ein Scheinmodul zum Testen bereit. Dieses Modul bietet eine Simulation der Daten in der Schaltung und erleichtert Entwicklern so den Unit-Test der Methoden im Vertrag. Konkrete Beispiele finden sich hier.

Vertrags-Debugging

console::debug(msg) zeigt Debuginformationen beim Debuggen eines Vertrags an. Die Nachrichteninformationen werden der Knotenprotokolldatei hinzugefügt. Voraussetzung ist, dass die Protokolldateiebene auf den Debugmodus eingestellt wird, wenn der lokale Ontology-Testknoten ausgeführt wird.

runtime::notify(msg) gibt die entsprechenden Debug-Informationen aus, während der Vertrag debuggt wird. Diese Methode speichert die in die Kette eingegebenen Informationen und kann mithilfe der getSmartCodeEvent-Methode von der Kette abgefragt werden.

Der Artikel wurde von den Herausgebern von Hashrate&Shares speziell für OntologyRussia übersetzt. клик

Sind Sie Entwickler? Treten Sie unserer Tech-Community bei Discord. Werfen Sie auch einen Blick auf Entwicklerzentrum auf unserer Website, wo Sie Entwicklertools, Dokumentation und mehr finden.

Ontologie

Source: habr.com

Kommentar hinzufügen