Plongez dans Move - le langage de programmation blockchain Libra de Facebook

Ensuite, nous examinerons en détail les principales caractéristiques du langage Move et quelles sont ses principales différences avec un autre langage déjà populaire pour les contrats intelligents - Solidity (sur la plate-forme Ethereum). Le matériel est basé sur une étude du livre blanc de 26 pages disponible en ligne.

introduction

Move est un langage de bytecode exécutable utilisé pour exécuter des transactions utilisateur et des contrats intelligents. Attention à deux points :

  1. Alors que Move est un langage de bytecode qui peut être exécuté directement sur la machine virtuelle Move, Solidity (le langage de contrat intelligent d'Ethereum) est un langage de niveau supérieur qui est d'abord compilé en bytecode avant d'être exécuté sur un EVM (Ethereum Virtual Machine).
  2. Move peut être utilisé non seulement pour implémenter des contrats intelligents, mais également pour des transactions personnalisées (nous en parlerons plus tard), tandis que Solidity est un langage réservé aux contrats intelligents.


La traduction a été réalisée par l’équipe du projet INDEX Protocol. Nous avons déjà traduit grand matériel décrivant le projet Libra, il est maintenant temps d’examiner le langage Move un peu plus en détail. La traduction a été réalisée conjointement avec Habrauser coolsiu

Une fonctionnalité clé de Move est la possibilité de définir des types de ressources personnalisés avec une sémantique basée sur une logique linéaire : une ressource ne peut jamais être copiée ou supprimée implicitement, mais seulement déplacée. Fonctionnellement, cela est similaire aux capacités du langage Rust. Les valeurs dans Rust ne peuvent être attribuées qu'à un seul nom à la fois. L'attribution d'une valeur à un nom différent la rend indisponible sous le nom précédent.

Plongez dans Move - le langage de programmation blockchain Libra de Facebook

Par exemple, l'extrait de code suivant génère une erreur : Utilisation de la valeur déplacée 'x'. C'est parce qu'il n'y a pas de ramasse-miettes dans Rust. Lorsque les variables sortent de la portée, la mémoire à laquelle elles se réfèrent est également libérée. En termes simples, il ne peut y avoir qu'un seul « propriétaire » des données. Dans cet exemple x est le propriétaire d'origine, puis y devient le nouveau propriétaire. En savoir plus sur ce comportement ici.

Représentation des actifs numériques dans les systèmes ouverts

Il existe deux propriétés des actifs physiques qui sont difficiles à représenter numériquement :

  • Rareté (Rareté, à l'origine rareté). Le nombre d'actifs (émissions) dans le système doit être contrôlé. La duplication d'actifs existants doit être interdite, et en créer de nouveaux est une opération privilégiée.
  • Contrôle d'accès... Le participant au système doit être en mesure de protéger les actifs à l'aide de stratégies de contrôle d'accès.

Ces deux caractéristiques, naturelles pour les actifs physiques, doivent être mises en œuvre pour les objets numériques si l'on veut les considérer comme des actifs. Par exemple, un métal rare - a une rareté naturelle, et vous seul y avez accès (le tenant dans vos mains, par exemple) et vous pouvez le vendre ou le dépenser.

Pour illustrer comment nous sommes arrivés à ces deux propriétés, commençons par les phrases suivantes :

Suggestion n°1 : La règle la plus simple sans pénurie ni contrôle d'accès

Plongez dans Move - le langage de programmation blockchain Libra de Facebook

  • G [K] : = n désigne une mise à jour d'un numéro accessible par une touche К dans l'état global de la blockchain, avec un nouveau sens n.
  • transaction Alice, 100⟩ signifie régler le solde du compte d'Alice à 100.

La solution ci-dessus présente plusieurs problèmes majeurs :

  • Alice peut recevoir un nombre illimité de pièces en envoyant simplement transaction Alice, 100⟩.
  • Les pièces qu'Alice envoie à Bob sont inutiles, car Bob pourrait s'envoyer un nombre illimité de pièces en utilisant la même technique.

Suggestion #2 : Prise en compte du déficit

Plongez dans Move - le langage de programmation blockchain Libra de Facebook

Maintenant, nous surveillons la situation afin que le nombre de pièces Ka était au moins égal n avant l'opération de transfert. Cependant, bien que cela résolve le problème de la rareté, il n'y a aucune information sur qui peut envoyer les pièces d'Alice (pour l'instant, tout le monde peut le faire, l'essentiel est de ne pas enfreindre la règle de limitation du montant).

Proposition n°3 : Conjuguer rareté et contrôle d'accès

Plongez dans Move - le langage de programmation blockchain Libra de Facebook

Nous résolvons ce problème avec un mécanisme de signature numérique vérifier_sig avant de vérifier le solde, ce qui signifie qu'Alice utilise sa clé privée pour signer la transaction et confirmer qu'elle est la propriétaire de ses pièces.

Langages de programmation Blockchain

Les langages blockchain existants sont confrontés aux problèmes suivants (tous ont été résolus dans Move (remarque : malheureusement, l'auteur de l'article ne fait appel qu'à Ethereum dans ses comparaisons, il vaut donc la peine de les prendre uniquement dans ce contexte. Par exemple, la plupart des éléments suivants sont également résolus dans EOS.)):

Représentation indirecte des actifs. Un actif est codé à l’aide d’un entier, mais un entier n’est pas la même chose qu’un actif. En fait, il n’existe aucun type ou valeur représentant Bitcoin/Ether/<Any Coin> ! Cela rend l’écriture de programmes utilisant des actifs difficile et sujette aux erreurs. Des modèles tels que le transfert d'actifs vers/depuis des procédures ou le stockage d'actifs dans des structures nécessitent une prise en charge spéciale de la part du langage.

Le déficit n'est pas extensible... La langue ne représente qu'un atout rare. De plus, les remèdes contre la pénurie sont directement intégrés dans la sémantique de la langue elle-même. Le développeur, s'il souhaite créer un actif personnalisé, doit contrôler soigneusement tous les aspects de la ressource lui-même. Ce sont exactement les problèmes des contrats intelligents Ethereum.

Les utilisateurs émettent leurs actifs, les jetons ERC-20, en utilisant des nombres entiers pour déterminer à la fois la valeur et l'offre totale. Chaque fois que de nouveaux jetons sont créés, le code du contrat intelligent doit vérifier de manière indépendante le respect des règles d'émission. De plus, la présentation indirecte des actifs conduit, dans certains cas, à de graves erreurs - duplication, double dépense voire perte totale des actifs.

Manque de contrôle d'accès flexible... La seule politique de contrôle d'accès en vigueur aujourd'hui est un schéma de signature utilisant la cryptographie asymétrique. Comme la protection contre la rareté, les politiques de contrôle d'accès sont profondément ancrées dans la sémantique du langage. Mais comment étendre le langage pour permettre aux programmeurs de définir leurs propres politiques de contrôle d'accès est souvent une tâche très délicate.

Cela est également vrai sur Ethereum, où les contrats intelligents ne prennent pas en charge la cryptographie native pour le contrôle d’accès. Les développeurs doivent définir manuellement le contrôle d'accès, par exemple à l'aide du modificateur onlyOwner.

Même si je suis un grand fan d'Ethereum, je pense que les propriétés des actifs doivent être nativement prises en charge par le langage pour des raisons de sécurité. En particulier, le transfert d'Ether vers un contrat intelligent implique une répartition dynamique, ce qui a introduit une nouvelle classe de bogues appelés vulnérabilités de réentrée. La répartition dynamique signifie ici que la logique d'exécution du code sera déterminée au moment de l'exécution (dynamique) plutôt qu'au moment de la compilation (statique).

Ainsi, dans Solidity, lorsque le contrat A appelle une fonction dans le contrat B, le contrat B peut exécuter du code qui n'était pas prévu par le développeur du contrat A, ce qui peut entraîner vulnérabilités de réentrée (le contrat A fait accidentellement office de contrat B pour retirer de l'argent avant que les soldes des comptes ne soient effectivement déduits).

Déplacer les principes fondamentaux de la conception linguistique

Ressources de premier ordre

A un niveau élevé, l'interaction entre modules/ressources/procédures dans le langage Move est très similaire à la relation entre classes/objets et méthodes dans les langages POO.
Les modules de déplacement sont similaires aux contrats intelligents dans d'autres blockchains. Le module déclare des types de ressources et des procédures qui définissent les règles de création, de destruction et de mise à jour des ressources déclarées. Mais tout cela ne sont que des conventions ("jargon”) Dans Déplacer. Nous illustrerons ce point un peu plus loin.

Flexibilité

Move ajoute de la flexibilité à Libra grâce aux scripts. Chaque transaction dans Libra comprend un script, qui constitue essentiellement la procédure principale de la transaction. Le script peut effectuer soit une action spécifiée, par exemple des paiements à une liste spécifiée de destinataires, soit réutiliser d'autres ressources - par exemple, en appelant une procédure dans laquelle la logique générale est spécifiée. C'est pourquoi les scripts de transaction Move offrent une plus grande flexibilité. Un script peut utiliser à la fois des comportements ponctuels et répétitifs, tandis qu'Ethereum ne peut exécuter que des scripts répétables (en appelant une méthode sur une méthode de contrat intelligent). La raison pour laquelle on l’appelle « réutilisable » est que les fonctions d’un contrat intelligent peuvent être exécutées plusieurs fois. (note: Le point ici est très subtil. D’une part, des scripts de transaction sous forme de pseudo-bytecode existent également dans Bitcoin. D'un autre côté, si je comprends bien, Move étend en fait ce langage au niveau d'un langage de contrat intelligent à part entière.).

sécurité

Le format exécutable Move est le bytecode, qui est, d'une part, un langage de niveau supérieur au langage assembleur, mais de niveau inférieur au code source. Le bytecode est vérifié au moment de l'exécution (en chaîne) pour les ressources, les types et la sécurité de la mémoire à l'aide d'un vérificateur de bytecode, puis exécuté par l'interpréteur. Cette approche permet à Move d'assurer la sécurité du code source, mais sans le processus de compilation et la nécessité d'ajouter un compilateur au système. Faire de Move un langage de bytecode est une très bonne solution. Il n'est pas nécessaire de le compiler à partir des sources, comme c'est le cas avec Solidity, et il n'y a pas lieu de s'inquiéter d'éventuelles pannes ou attaques sur l'infrastructure du compilateur.

Vérifiabilité

Notre objectif est d'effectuer les contrôles aussi facilement que possible, puisque tout cela se fait en chaîne (remarque : en ligne, lors de l'exécution de chaque transaction, donc tout retard entraîne un ralentissement de l'ensemble du réseau), cependant, dans un premier temps, la conception du langage est prête à utiliser des outils de vérification statique hors chaîne. Bien que cela soit préférable, pour l'instant, le développement d'outils de vérification (en tant que boîte à outils distincte) a été reporté à l'avenir, et désormais seule la vérification dynamique au moment de l'exécution (en chaîne) est prise en charge.

Modularité

Les modules de déplacement fournissent une abstraction des données et localisent les opérations critiques sur les ressources. L'encapsulation fournie par le module, combinée à la protection fournie par le système de type Move, garantit que les propriétés définies sur les types du module ne peuvent pas être violées par du code extérieur au module. Il s'agit d'une conception d'abstraction assez bien pensée, ce qui signifie que les données d'un contrat ne peuvent changer que dans le cadre du contrat, mais pas de l'extérieur.

Plongez dans Move - le langage de programmation blockchain Libra de Facebook

Aperçu du déplacement

L'exemple de script de transaction démontre que les actions malveillantes ou imprudentes d'un programmeur en dehors d'un module ne peuvent pas compromettre la sécurité des ressources d'un module. Ensuite, nous examinerons des exemples d'utilisation des modules, des ressources et des procédures pour programmer la blockchain Libra.

Paiements de pair à pair

Plongez dans Move - le langage de programmation blockchain Libra de Facebook

Le nombre de pièces spécifié en montant sera transféré du solde de l'expéditeur au destinataire.
Il y a quelques nouveautés ici (surlignées en rouge) :

  • Assistance : adresse du compte où est stocké le module
  • Devise: nom du module
  • Coin: type de ressource
  • La valeur de pièce renvoyée par la procédure est une valeur de ressource de type 0x0.Currency.Coin
  • mouvement (): la valeur ne peut pas être réutilisée
  • copie(): la valeur peut être utilisée plus tard

Analyser le code : dans la première étape, l'expéditeur appelle une procédure nommée retirer_de_l'expéditeur à partir d'un module stocké dans 0x0.Devise. Dans la deuxième étape, l'expéditeur transfère les fonds au destinataire en déplaçant la valeur de la ressource en pièces dans la procédure de dépôt du module. 0x0.Devise.

Voici trois exemples d’erreurs de code qui seront rejetées par les contrôles :
Dupliquer des fonds en modifiant l'appel déplacer (pièce) sur copie (pièce). Les ressources peuvent uniquement être déplacées. Tenter de dupliquer une quantité d'une ressource (par exemple, en appelant copie (pièce) dans l'exemple ci-dessus) entraînera une erreur lors de la vérification du bytecode.

Réutilisation des fonds en précisant déplacer (pièce) deux fois . Ajouter une ligne 0x0.Currency.deposit (copie (some_other_payee), déplacement (pièce)) par exemple, ce qui précède permettra à l'expéditeur de « dépenser » les pièces deux fois : la première fois avec le bénéficiaire et la seconde avec some_other_payee. Il s’agit d’un comportement indésirable qui n’est pas possible avec un actif physique. Heureusement, Move rejettera ce programme.

Perte de fonds suite à un refus déplacer (pièce). Si vous ne déplacez pas la ressource (par exemple en supprimant la ligne contenant déplacer (pièce)), une erreur de vérification du bytecode sera générée. Cela protège les programmeurs Move contre la perte de fonds accidentelle ou malveillante.

Module Devise

Plongez dans Move - le langage de programmation blockchain Libra de Facebook

Chaque compte peut contenir 0 ou plusieurs modules (représentés sous forme de rectangles) et une ou plusieurs valeurs de ressources (représentées sous forme de cylindres). Par exemple, un compte sur Assistance contient un module 0x0.Devise et la valeur du type de ressource 0x0.Currency.Coin. Compte à l'adresse Assistance dispose de deux ressources et d'un module ; Compte à l'adresse Assistance a deux modules et une valeur de ressource.

Quelques moments:

  • Le script de transaction est atomique : soit il est exécuté complètement, soit pas du tout.
  • Un module est un morceau de code de longue durée accessible mondialement.
  • L'état global est structuré sous forme de table de hachage, où la clé est l'adresse du compte
  • Les comptes ne peuvent contenir qu'une seule valeur de ressource d'un type donné et pas plus d'un module portant un nom donné (compte à l'adresse Assistance ne peut pas contenir de ressource supplémentaire 0x0.Currency.Coin ou un autre module nommé Devise)
  • L'adresse du module déclaré fait partie du type (0x0.Currency.Coin и 0x1.Currency.Coin sont des types distincts qui ne peuvent pas être utilisés de manière interchangeable)
  • Les programmeurs peuvent stocker plusieurs instances de ce type de ressource dans un compte en définissant leur ressource personnalisée - (ressource TwoCoins {c1 : 0x0.Currency.Coin, c2 : 0x0.Currency.Coin})
  • Vous pouvez faire référence à une ressource par son nom sans conflits, par exemple vous pouvez faire référence à deux ressources en utilisant DeuxCoins.c1 и DeuxCoins.c2.

Annonce des ressources en pièces

Plongez dans Move - le langage de programmation blockchain Libra de Facebook
Module nommé Devise et un type de ressource nommé Coin

Quelques moments:

  • Coin est une structure avec un champ de type u64 (entier non signé de 64 bits)
  • Procédures du module uniquement Devise peut créer ou détruire des valeurs de type Coin.
  • Les autres modules et scripts ne peuvent écrire ou référencer le champ de valeur que via des procédures publiques fournies par le module.

Vente de dépôt

Plongez dans Move - le langage de programmation blockchain Libra de Facebook

Cette procédure accepte une ressource Coin comme entrée et la combine avec la ressource Coinstockés dans le compte du destinataire :

  1. Détruire la ressource d'entrée Coin et enregistrer sa valeur.
  2. Recevoir un lien vers une ressource Coin unique stockée dans le compte du destinataire.
  3. Modification de la valeur du nombre de Coins par la valeur passée en paramètre lors de l'appel de la procédure.

Quelques moments:

  • Déballer, emprunterGlobal - procédures intégrées
  • Déballer C'est le seul moyen de supprimer une ressource de type T. La procédure prend une ressource en entrée, la détruit et renvoie la valeur associée aux champs de la ressource.
  • EmprunterGlobal prend une adresse en entrée et renvoie une référence à une instance unique de T publiée (détenue) par cette adresse
  • &mut Pièce ceci est un lien vers la ressource Coin

Implémentation de Remove_from_sender

Plongez dans Move - le langage de programmation blockchain Libra de Facebook

Cette procédure:

  1. Obtient un lien vers une ressource unique Coin, lié au compte de l'expéditeur
  2. Diminue la valeur d'une ressource Coin via le lien pour le montant indiqué
  3. Crée et renvoie une nouvelle ressource Coin avec solde mis à jour.

Quelques moments:

  • Caution peut être causé par n'importe qui, mais retirer_de_l'expéditeur n'a accès qu'aux pièces du compte appelant
  • GetTxnSenderAddress semblable à msg.expéditeur en Solidité
  • RejeterSauf semblable à exigent en Solidité. Si cette vérification échoue, la transaction est arrêtée et toutes les modifications sont annulées.
  • Paquet c'est aussi une procédure intégrée qui crée une nouvelle ressource de type T.
  • Aussi bien que Déballer, Paquet ne peut être appelé qu'à l'intérieur du module où la ressource est décrite T

Conclusion

Nous avons examiné les principales caractéristiques du langage Move, l'avons comparé à Ethereum et nous sommes également familiarisés avec la syntaxe de base des scripts. Enfin, je recommande fortement de consulter livre blanc original. Il comprend de nombreux détails sur les principes de conception des langages de programmation, ainsi que de nombreux liens utiles.

Source: habr.com

Ajouter un commentaire