Come scrivere un contratto smart su WebAssembly nella rete Ontology? Parte 1: Rust

Come scrivere un contratto smart su WebAssembly nella rete Ontology? Parte 1: Rust

La tecnologia Ontology Wasm riduce il costo del trasferimento dei contratti smart dApp con logiche di business complesse sulla blockchain, arricchendo notevolmente l'ecosistema dApp.

Attualmente Ontology Wasm supporta contemporaneamente lo sviluppo sia in Rust che in C++. Il linguaggio Rust offre una migliore compatibilità con Wasm e il bytecode generato è più semplice, il che può ulteriormente ridurre i costi delle chiamate contrattuali. Quindi, come utilizzare Rust per sviluppare un contratto sulla rete Ontology?

Sviluppo di contratti WASM con Rust

Creazione di un contratto

Cargo è uno strumento utile per la creazione di progetti e la gestione dei pacchetti durante lo sviluppo di programmi in Rust, aiutando gli sviluppatori a organizzare meglio l'interazione tra codice e librerie esterne. Per creare un nuovo contratto Ontology Wasm, basta eseguire il seguente comando:

Come scrivere un contratto smart su WebAssembly nella rete Ontology? Parte 1: Rust

La struttura del progetto che genera:

Come scrivere un contratto smart su WebAssembly nella rete Ontology? Parte 1: Rust

Il file Cargo.toml è utilizzato per configurare le informazioni di base del progetto e le informazioni sulla libreria dipendente. La sezione [lib] nel file deve essere impostata sul valore crate-type = ["cdylib"]. Il file lib.rs è utilizzato per scrivere il codice della logica del contratto. Inoltre, è necessario aggiungere i parametri delle dipendenze nella sezione [dependencies] del file di configurazione Cargo.toml:

Come scrivere un contratto smart su WebAssembly nella rete Ontology? Parte 1: Rust

Con questa dipendenza, gli sviluppatori possono chiamare interfacce che interagiscono con la blockchain Ontology e strumenti come il parametro di serializzazione.

Funzione di ingresso del contratto

Ogni programma ha una funzione di ingresso, come ad esempio la funzione main, che vediamo di solito, ma il contratto non ha una funzione main. Quando si sviluppa un contratto Wasm utilizzando Rust, la funzione invoke viene utilizzata come funzione di ingresso per l'uso del contratto. Il nome della funzione in Rust sarà ambiguo durante la compilazione del codice sorgente Rust in bytecode, che può essere eseguito dalla macchina virtuale. Per prevenire che il compilatore generi codice ridondante e ridurre le dimensioni del contratto, la funzione invoke aggiunge l'annotazione #[no_mangle].

Come ottiene i parametri la funzione invoke per eseguire una transazione?

La libreria ontio_std fornisce la funzione runtime::input() per ottenere i parametri necessari all'esecuzione della transazione. Gli sviluppatori possono utilizzare ZeroCopySource per deserializzare l'array di byte ricevuto, dove il primo array di byte letto è il nome del metodo invoke, seguito dai parametri del metodo.

Come viene restituito il risultato dell'esecuzione del contratto?

La funzione runtime::ret, fornita dalla libreria ontio_std, restituisce il risultato dell'esecuzione del metodo.

La funzione invoke completata appare nel seguente modo:

Come scrivere un contratto smart su WebAssembly nella rete Ontology? Parte 1: Rust

Serializzazione e deserializzazione dei dati del contratto

Durante lo sviluppo dei contratti, gli sviluppatori si imbattono sempre in problemi di serializzazione e deserializzazione, in particolare su come salvare i dati di tipo struct nel database e come deserializzare un array di byte letto dal database per ottenere dati di tipo struct.

La libreria ontio_std fornisce interfacce per il decodificatore e il codificatore per la serializzazione e deserializzazione dei dati. I campi della struttura struct implementano anche interfacce per il decodificatore e il codificatore, così che la struttura possa essere serializzata e deserializzata. Le istanze della classe Sink sono necessarie quando si serializzano vari tipi di dati. Un'istanza della classe Sink ha un campo di tipo set buf, che memorizza dati di tipo byte, e tutti i dati serializzati sono memorizzati in buf.

Per i dati di lunghezza fissa (ad esempio: byte, u16, u32, u64, ecc.) i dati vengono trasformati direttamente in un array di byte e quindi salvati in buf; per i dati di lunghezza variabile, è necessario prima serializzare la lunghezza e poi i dati (ad esempio, numeri interi senza segno di dimensioni sconosciute, inclusi u16, u32 o u64, ecc.).

La deserializzazione è l'opposto diretto. Per ogni metodo di serializzazione esiste un corrispondente metodo di deserializzazione. La deserializzazione richiede l'uso di istanze della classe Source. Questa classe ha due campi: buf e pos. Buf viene utilizzato per memorizzare i dati da deserializzare, mentre pos serve a memorizzare la posizione di lettura corrente. Quando viene letto un tipo di dato specifico, se conosci la sua lunghezza, puoi leggerlo direttamente; per i dati di lunghezza sconosciuta, prima leggi la lunghezza e poi il contenuto.

Accesso e aggiornamento dei dati nella catena

Ontology-wasm-cdt-rust — ha incapsulato il metodo operativo per lavorare con i dati nella catena, rendendolo conveniente per gli sviluppatori per implementare operazioni come l'aggiunta, la rimozione, la modifica e la richiesta di dati nella catena nel modo seguente:

  • database::get(key) — viene utilizzato per richiedere dati dalla catena, e key richiede l'implementazione dell'interfaccia AsRef;
  • database::put(key, value) — viene utilizzato per memorizzare dati nella rete. Key richiede l'esecuzione dell'interfaccia AsRef, e value richiede l'implementazione dell'interfaccia Encoder;
  • database::delete(key) — viene utilizzato per rimuovere dati dalla blockchain, mentre la chiave richiede l'implementazione dell'interfaccia AsRef.

Test del contratto

Quando vengono implementati i metodi del contratto, abbiamo bisogno di accedere ai dati nella blockchain e di una macchina virtuale adeguata per eseguire il bytecode del contratto. Pertanto, è solitamente necessario distribuire il contratto nella blockchain per il test. Tuttavia, questo metodo di test presenta delle problematiche. Per facilitare il lavoro degli sviluppatori nella verifica dei contratti, la libreria ontio_std fornisce un modulo mock per il testing. Questo modulo simula i dati nella blockchain, rendendo più semplice per gli sviluppatori effettuare unit test dei metodi nel contratto. Esempi specifici possono essere trovati qui.

Debugging del contratto

console::debug(msg) stampa informazioni di debug durante il processo di debugging del contratto. L'informazione msg verrà registrata nel file di log del nodo. È obbligatorio impostare il livello del file di log in modalità debug quando viene eseguito un nodo di test locale di Ontology.

runtime::notify(msg) visualizza le informazioni di debug pertinenti durante il debug del contratto. Questo metodo salverà le informazioni fornite nella catena e potrà essere richiesto dalla catena tramite il metodo getSmartCodeEvent.

L'articolo è stato tradotto dall'editoria Hashrate&Shares appositamente per OntologyRussia. clicca

Sei uno sviluppatore? Unisciti alla nostra comunità tecnica su Discord. Inoltre, dai un'occhiata a Centro Sviluppatori sul nostro sito, dove puoi trovare strumenti per sviluppatori, documentazione e molto altro.

Ontology

Fonte: habr.com

Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server 🔥 Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server | ProHoster