Wie schreibt man einen Smart Contract auf WebAssembly im Ontology Netzwerk? Teil 1: Rust

Wie schreibt man einen Smart Contract auf WebAssembly im Ontology Netzwerk? Teil 1: Rust

Die Ontology Wasm-Technologie senkt die Kosten für die Migration von dApp-Smart Contracts mit komplexer Geschäftlogik auf die Blockchain und bereichert somit das dApp-Ökosystem erheblich.

Derzeit Ontology Wasm unterstützt sowohl die Entwicklung in Rust als auch in C++. Rust unterstützt Wasm besser, und der generierte Bytecode ist einfacher, was die Kosten für Vertragsaufrufe weiter senken kann. Daher wie verwendet man Rust zur Entwicklung eines Vertrags im Ontology-Netzwerk?

Entwicklung eines WASM-Vertrags mit Rust

Vertragserstellung

Cargo ist ein hilfreiches Projektmanagement- und Paketverwaltungstool für die Programmierung in Rust, das Entwicklern hilft, die Interaktion zwischen ihrem Code und externen Bibliotheken besser zu organisieren. Um einen neuen Ontology Wasm-Vertrag zu erstellen, führen Sie einfach den folgenden Befehl aus:

Wie schreibt man einen Smart Contract auf WebAssembly im Ontology Netzwerk? Teil 1: Rust

Die Projektstruktur, die es generiert:

Wie schreibt man einen Smart Contract auf WebAssembly im Ontology Netzwerk? Teil 1: Rust

Die Datei Cargo.toml wird verwendet, um grundlegende Informationen über das Projekt und die abhängigen Bibliotheken zu konfigurieren. Der Abschnitt [lib] in der Datei muss auf crate-type = ["cdylib"] gesetzt werden. Die Datei lib.rs wird verwendet, um die Logik des Vertrags zu implementieren. Zudem müssen Sie die Abhängigkeitsparameter im Abschnitt [dependencies] der Konfigurationsdatei Cargo.toml hinzufügen:

Wie schreibt man einen Smart Contract auf WebAssembly im Ontology Netzwerk? Teil 1: Rust

Mit dieser Abhängigkeit können Entwickler Schnittstellen aufrufen, die mit der Ontology-Blockchain interagieren, sowie Werkzeuge wie den Serialisierungsparameter.

Eingabefunktion des Vertrags

Jedes Programm hat eine Eingabefunktion, wie die main-Funktion, die wir normalerweise sehen, aber ein Vertrag hat keine main-Funktion. Wenn ein Wasm-Vertrag mit Rust entwickelt wird, wird die Funktion invoke standardmäßig als Eingabefunktion für den Vertrag verwendet. Der Name der Funktion in Rust bleibt bei der Kompilierung des Rust-Quellcodes in Bytecode, der von der virtuellen Maschine ausgeführt werden kann, unklar. Um den Compiler daran zu hindern, überflüssigen Code zu generieren und die Größe des Vertrags zu reduzieren, fügt die Funktion invoke die Annotation #[no_mangle] hinzu.

Wie erhält die Funktion invoke Parameter zur Ausführung einer Transaktion?

Die Bibliothek ontio_std stellt die Funktion runtime::input() zur Verfügung, um Parameter für die Ausführung von Transaktionen zu erhalten. Entwickler können ZeroCopySource zur Deserialisierung des erhaltenen Byte-Arrays verwenden. Das erste gelesene Byte-Array ist der Name der invoke-Methode, gefolgt von den Methodenparametern.

Wie wird das Ergebnis der Vertragserfüllung zurückgegeben?

Die Funktion runtime::ret, die von der Bibliothek ontio_std bereitgestellt wird, gibt das Ergebnis der Methodenimplementierung zurück.

Die vollständige invoke-Funktion sieht folgendermaßen aus:

Wie schreibt man einen Smart Contract auf WebAssembly im Ontology Netzwerk? Teil 1: Rust

Serialisierung und Deserialisierung von Vertragsdaten

Bei der Entwicklung von Verträgen stoßen Entwickler häufig auf Probleme mit der Serialisierung und Deserialisierung, insbesondere darauf, wie Datentypen vom struct-Typ in einer Datenbank gespeichert und wie Byte-Arrays, die aus der Datenbank gelesen werden, deserialisiert werden, um den struct-Datentyp zu erhalten.

Die Bibliothek ontio_std bietet Decoder- und Encoder-Schnittstellen für die Serialisierung und Deserialisierung von Daten an. Die Felder der Struktur struct implementieren ebenfalls Decoder- und Encoder-Schnittstellen, sodass die Struktur serialisiert und deserialisiert werden kann. Instanzen der Klasse Sink sind erforderlich, wenn verschiedene Datentypen serialisiert werden. Eine Instanz der Klasse Sink hat ein set-Feld vom Typ buf, das die Byte-Daten speichert, während alle serialisierten Daten in buf gespeichert werden.

Für festgelegte Datentypen (z. B.: byte, u16, u32, u64 usw.) werden die Daten direkt in ein Byte-Array umgewandelt und dann in buf gespeichert; für variable Datentypen muss zunächst die Länge serialisiert und dann Ddata (z. B. Vorzeichenlose Ganzzahlen unbekannter Größe, einschließlich u16, u32 oder u64 usw.) verarbeitet werden.

Die Deserialisierung ist das genaue Gegenteil. Für jede Serialisierungsmethode gibt es die entsprechende Deserialisierungsmethode. Die Deserialisierung erfordert die Verwendung von Instanzen der Klasse Source. Diese Instanz hat zwei Felder: buf und pos. Buf wird verwendet, um die Daten zu speichern, die deserialisiert werden, während pos verwendet wird, um die aktuelle Leseposition zu speichern. Wenn ein bestimmter Datentyp gelesen wird und seine Länge bekannt ist, können Sie ihn direkt lesen; für unbekannte Längen muss zuerst die Länge und dann der Inhalt gelesen werden.

Zugriff auf und Aktualisierung von Daten in der Kette

Ontology-wasm-cdt-rust — kapselte die betriebliche Methode zur Arbeit mit Daten in der Blockchain ein, die für Entwickler praktisch ist, um Operationen wie Hinzufügen, Löschen, Ändern und Abfragen von Daten in der Blockchain wie folgt durchzuführen:

  • datenbank::get(key) — wird verwendet, um Daten aus der Blockchain abzufragen, wobei key die Implementierung des AsRef-Interfaces abfrägt;
  • datenbank::put(key, value) — wird verwendet, um Daten im Netzwerk zu speichern. Key fragt die Ausführung des AsRef-Interfaces ab, während value die Implementierung des Encoder-Interfaces abfragt;
  • datenbank::delete(key) — wird verwendet, um Daten aus der Kette zu löschen, wobei key die Implementierung des AsRef-Interfaces abfragt.

Vertragsprüfung

Wenn die Methoden des Vertrags implementiert werden, benötigen wir Zugriff auf die Daten in der Blockchain und wir benötigen eine entsprechende virtuelle Maschine, um den Bytecode des Vertrags auszuführen. Daher ist es in der Regel notwendig, den Vertrag zur Prüfung in der Blockchain bereitzustellen. Doch diese Methode der Prüfung ist problematisch. Um die Prüfung von Verträgen für Entwickler zu erleichtern, bietet die Bibliothek ontio_std ein Mock-Modul für Tests. Dieses Modul simuliert Daten in der Blockchain, um für Entwickler das Unit-Testing von Methoden im Vertrag zu erleichtern. Konkrete Beispiele sind verfügbar hier.

Vertragsdebugging

console::debug(msg) gibt Debug-Informationen während des Debuggings des Vertrags aus. Die Information msg wird in die Log-Datei des Knotens aufgenommen. Eine Voraussetzung ist die Einstellung des Log-Datei-Levels in den Debug-Modus, wenn der lokale Test-Knoten von Ontology läuft.

runtime::notify(msg) gibt relevante Debug-Informationen während des Debuggings des Vertrags aus. Diese Methode speichert die eingegebene Information in der Blockchain und kann mit der Methode getSmartCodeEvent aus der Blockchain abgerufen werden.

Der Artikel wurde von der Redaktion Hashrate&Shares speziell für OntologyRussia übersetzt. Klick

Sind Sie Entwickler? Treten Sie unserer technischen Gemeinschaft bei auf Discord. Schauen Sie auch in das Entwicklerzentrum auf unserer Website, wo Sie Entwicklerwerkzeuge, Dokumentationen und vieles mehr finden können.

Ontology

Quelle: habr.com

Zuverlässiges Hosting für Websites mit DDoS-Schutz kaufen, VPS VDS Server 🔥 Zuverlässiges Hosting für Websites mit DDoS-Schutz kaufen, VPS VDS Server - ProHoster