Comment rédiger un smart contract WebAssembly sur le réseau Ontology ? Partie 1 : Rouille

Comment rédiger un smart contract WebAssembly sur le réseau Ontology ? Partie 1 : Rouille

La technologie Ontology Wasm réduit le coût de la migration des contrats intelligents dApp avec une logique métier complexe vers la blockchain, enrichissant ainsi considérablement l'écosystème dApp.

Maintenant Ontologie Wasm Prend en charge simultanément le développement Rust et C++. Le langage Rust prend mieux en charge Wasm et le bytecode généré est plus simple, ce qui peut encore réduire le coût des appels de contrat. Donc, comment utiliser Rust pour développer un contrat sur le réseau Ontology ?

Développer un contrat WASM avec Rust

Créer un contrat

Cargaison est un bon outil de création de projets et de gestion de packages pour le développement Rust, qui aide les développeurs à mieux organiser l'interaction du code et des bibliothèques tierces. Pour créer un nouveau contrat Ontology Wasm, exécutez simplement la commande suivante :

Comment rédiger un smart contract WebAssembly sur le réseau Ontology ? Partie 1 : Rouille

La structure de projet qu'il génère :

Comment rédiger un smart contract WebAssembly sur le réseau Ontology ? Partie 1 : Rouille

Le fichier Cargo.toml est utilisé pour configurer les informations de base du projet et les informations de bibliothèque dépendantes. La section [lib] du fichier doit être définie sur crate-type = ["cdylib"]. Le fichier lib.rs est utilisé pour écrire le code logique du contrat. De plus, vous devez ajouter des paramètres de dépendance à la section [dependencies] du fichier de configuration Cargo.toml :

Comment rédiger un smart contract WebAssembly sur le réseau Ontology ? Partie 1 : Rouille

Avec cette dépendance, les développeurs peuvent appeler des interfaces qui interagissent avec la blockchain Ontology et des outils tels que le paramètre de sérialisation.

Fonction de saisie de contrat

Chaque programme a une fonction d'entrée, comme la fonction principale que nous voyons habituellement, mais le contrat n'a pas de fonction principale. Lorsqu'un contrat Wasm est développé à l'aide de Rust, la fonction d'appel par défaut est utilisée comme fonction d'entrée pour utiliser le contrat. Le nom d'une fonction dans Rust ne sera pas clair lors de la compilation du code source Rust en bytecode pouvant être exécuté par une machine virtuelle. Pour empêcher le compilateur de générer du code redondant et réduire la taille du contrat, la fonction d'appel ajoute l'annotation #[no_mangle].

Comment la fonction d'appel obtient-elle des paramètres pour exécuter une transaction ?

La bibliothèque ontio_std fournit une fonction runtime::input() pour obtenir les paramètres pour exécuter une transaction. Les développeurs peuvent utiliser ZeroCopySource pour désérialiser le tableau d'octets résultant. Dans lequel le premier tableau d'octets lus est le nom de la méthode d'appel, suivi des paramètres de la méthode.

Comment le résultat de l'exécution du contrat est-il renvoyé ?

La fonction runtime::ret fournie par la bibliothèque ontio_std renvoie le résultat de l'exécution d'une méthode.

La fonction d'appel terminée ressemble à ceci :

Comment rédiger un smart contract WebAssembly sur le réseau Ontology ? Partie 1 : Rouille

Sérialisation et désérialisation des données de contrat

Lors du développement de contrats, les développeurs rencontrent toujours des problèmes de sérialisation et de désérialisation, en particulier avec la manière de stocker un type de données struct dans la base de données et de désérialiser un tableau d'octets lu à partir de la base de données pour obtenir un type de données struct.

La bibliothèque ontio_std fournit des interfaces de décodeur et d'encodeur pour la sérialisation et la désérialisation des données. Les champs d'une structure implémentent également les interfaces de décodeur et d'encodeur afin que la structure puisse être sérialisée et désérialisée. Les instances de la classe Sink sont requises lorsque divers types de données sont sérialisés. Une instance de la classe Sink a un champ de type ensemble buf qui stocke les données de type octet, et toutes les données sérialisées sont stockées dans buf.

Pour les données de longueur fixe (par exemple : octet, u16, u32, u64, etc.), les données sont directement converties en un tableau d'octets puis stockées dans buf ; pour les données de longueur non fixe, la longueur doit être sérialisée en premier, puis Ddata (par exemple, des entiers non signés de taille inconnue, y compris u16, u32 ou u64, etc.).

La désérialisation est exactement le contraire. Pour chaque méthode de sérialisation, il existe une méthode de désérialisation correspondante. La désérialisation nécessite l'utilisation d'instances de la classe Source. Cette instance de classe a deux champs buf et pos. Buf est utilisé pour stocker les données à désérialiser et pos est utilisé pour stocker la position de lecture actuelle. Lorsqu'un type particulier de données est en cours de lecture, si vous connaissez sa longueur, vous pouvez le lire directement, pour les données de longueur inconnue - lisez d'abord la longueur, puis lisez le contenu.

Accéder et mettre à jour les données de la chaîne

ontologie-wasm-cdt-rouille - encapsulé une méthode opérationnelle pour travailler avec les données dans la chaîne, ce qui est pratique pour les développeurs pour mettre en œuvre des opérations telles que l'ajout, la suppression, la modification et l'interrogation des données dans la chaîne comme suit :

  • base de données :: obtenir (clé) - est utilisé pour demander des données à la chaîne, et la clé demande la mise en œuvre de l'interface AsRef ;
  • base de données :: put (clé, valeur) - utilisé pour stocker des données sur le réseau. La clé demande l'implémentation de l'interface AsRef et la valeur demande l'implémentation de l'interface Encoder ;
  • base de données :: supprimer (clé) - est utilisé pour supprimer des données de la chaîne, et la clé demande la mise en œuvre de l'interface AsRef.

Essais contractuels

Lorsque les méthodes d'un contrat sont implémentées, nous avons besoin d'accéder aux données sur la chaîne et nous avons besoin d'une machine virtuelle appropriée pour exécuter le bytecode du contrat, il est donc généralement nécessaire de déployer le contrat sur la chaîne pour le tester. Mais cette méthode de test est problématique. Pour permettre aux développeurs de tester plus facilement les contrats, la bibliothèque ontio_std fournit un module fictif pour les tests. Ce module fournit une simulation des données dans le circuit, ce qui permet aux développeurs de tester plus facilement les méthodes dans le contrat. Des exemples concrets peuvent être trouvés ici.

Débogage de contrat

console::debug(msg) affiche les informations de débogage lors du débogage d'un contrat. Les informations msg seront ajoutées au fichier journal du nœud. Une condition préalable consiste à définir le niveau du fichier journal sur le mode débogage lorsque le nœud de test d'ontologie local est en cours d'exécution.

runtime::notify(msg) génère les informations de débogage appropriées pendant le débogage du contrat. Cette méthode stockera les informations saisies dans la chaîne et pourra être interrogée à partir de la chaîne à l'aide de la méthode getSmartCodeEvent.

L'article a été traduit par les éditeurs de Hashrate&Shares spécialement pour OntologyRussia. клик

Vous êtes développeur? Rejoignez notre communauté technologique sur Discorde. Aussi, jetez un oeil à Centre de développement sur notre site Web, où vous trouverez des outils de développement, de la documentation, etc.

Ontologie

Source: habr.com

Ajouter un commentaire