Aider à mettre à jour cette page

🌏

Il existe une nouvelle version de cette page, mais seulement en anglais pour le moment. Aidez-nous à traduire la dernière version.

Cette page est incomplète. Si vous êtes un expert sur le sujet, veuillez éditer cette page et l'enrichir de votre sagesse.

Langages des contrats intelligents

Dernière modification: , Invalid DateTime
Edit page

Un aspect important d'Ethereum est que les contrats intelligents peuvent être programmés en utilisant des langages relativement conviviaux pour les développeurs. Si vous avez de l'expérience avec Python ou JavaScript, vous pouvez utiliser un langage disposant d'une syntaxe similaire.

Les deux langages les plus actifs et les plus suivis sont :

  • Solidity
  • Vyper

Des développeurs plus expérimentés peuvent choisir d'utiliser Yul, un langage intermédiaire pour la machine virtuelle Ethereum (EVM), ou Yul+, une extension de Yul.

Prérequis

La connaissance de langages de programmation comme JavaScript ou Python peut vous aider à comprendre les différences entre les langages de contrats intelligents. Nous vous conseillons également d'avoir compris le concept des contrats intelligents avant de vous plonger dans les comparaisons entre les différents langages. Lire la page Introduction aux contrats intelligents

Solidity

  • Influencé par C++, Python et JavaScript
  • Typé statistiquement (le type d'une variable est connu au moment de la compilation)
  • Prend en charge les éléments suivants :
    • Héritage : Vous pouvez prolonger d'autres contrats.
    • Bibliothèques : Vous pouvez créer du code réutilisable que vous pouvez appeler à partir de différents contrats, comme les fonctions statiques d'une classe statique dans d'autres langages de programmation orientés objets.
    • Types complexes défini par l'utilisateur

Exemple de contrat

1// SPDX-License-Identifier: GPL-3.0
2pragma solidity >= 0.7.0;
3
4contract Coin {
5 // The keyword "public" makes variables
6 // accessible from other contracts
7 address public minter;
8 mapping (address => uint) public balances;
9
10 // Events allow clients to react to specific
11 // contract changes you declare
12 event Sent(address from, address to, uint amount);
13
14 // Constructor code is only run when the contract
15 // is created
16 constructor() {
17 minter = msg.sender;
18 }
19
20 // Sends an amount of newly created coins to an address
21 // Can only be called by the contract creator
22 function mint(address receiver, uint amount) public {
23 require(msg.sender == minter);
24 require(amount < 1e60);
25 balances[receiver] += amount;
26 }
27
28 // Sends an amount of existing coins
29 // from any caller to an address
30 function send(address receiver, uint amount) public {
31 require(amount <= balances[msg.sender], "Insufficient balance.");
32 balances[msg.sender] -= amount;
33 balances[receiver] += amount;
34 emit Sent(msg.sender, receiver, amount);
35 }
36}
37
Afficher tout
📋 Copier

Cet exemple devrait vous donner une idée de la syntaxe d'un contrat Solidity. Pour une description plus détaillée des fonctions et des variables, consultez la documentation.

Vyper

  • Langage de programmation pythonique
  • Typage fort
  • Code de compilation concis et compréhensible
  • A intentionnellement moins de fonctionnalités que Solidity dans le but de rendre les contrats plus sécurisés et plus faciles à auditer . Vyper ne prend pas en charge les éléments suivants :
    • Modificateurs
    • Héritage
    • Assemblage en ligne
    • Surcharge des fonctions
    • Surcharge d’opérateur
    • Appels récurrent
    • Boucles infinies
    • Points fixes binaires

Pour plus d'informations, lisez cette page Vyper.

Exemple

1# Open Auction
2
3# Auction params
4# Beneficiary receives money from the highest bidder
5beneficiary: public(address)
6auctionStart: public(uint256)
7auctionEnd: public(uint256)
8
9# Current state of auction
10highestBidder: public(address)
11highestBid: public(uint256)
12
13# Set to true at the end, disallows any change
14ended: public(bool)
15
16# Keep track of refunded bids so we can follow the withdraw pattern
17pendingReturns: public(HashMap[address, uint256])
18
19# Create a simple auction with `_bidding_time`
20# seconds bidding time on behalf of the
21# beneficiary address `_beneficiary`.
22@external
23def __init__(_beneficiary: address, _bidding_time: uint256):
24 self.beneficiary = _beneficiary
25 self.auctionStart = block.timestamp
26 self.auctionEnd = self.auctionStart + _bidding_time
27
28# Bid on the auction with the value sent
29# together with this transaction.
30# The value will only be refunded if the
31# auction is not won.
32@external
33@payable
34def bid():
35 # Check if bidding period is over.
36 assert block.timestamp < self.auctionEnd
37 # Check if bid is high enough
38 assert msg.value > self.highestBid
39 # Track the refund for the previous high bidder
40 self.pendingReturns[self.highestBidder] += self.highestBid
41 # Track new high bid
42 self.highestBidder = msg.sender
43 self.highestBid = msg.value
44
45# Withdraw a previously refunded bid. The withdraw pattern is
46# used here to avoid a security issue. If refunds were directly
47# sent as part of bid(), a malicious bidding contract could block
48# those refunds and thus block new higher bids from coming in.
49@external
50def withdraw():
51 pending_amount: uint256 = self.pendingReturns[msg.sender]
52 self.pendingReturns[msg.sender] = 0
53 send(msg.sender, pending_amount)
54
55# End the auction and send the highest bid
56# to the beneficiary.
57@external
58def endAuction():
59 # It is a good guideline to structure functions that interact
60 # with other contracts (i.e. they call functions or send Ether)
61 # into three phases:
62 # 1. checking conditions
63 # 2. performing actions (potentially changing conditions)
64 # 3. interacting with other contracts
65 # If these phases are mixed up, the other contract could call
66 # back into the current contract and modify the state or cause
67 # effects (ether payout) to be performed multiple times.
68 # If functions called internally include interaction with external
69 # contracts, they also have to be considered interaction with
70 # external contracts.
71
72 # 1. Conditions
73 # Check if auction endtime has been reached
74 assert block.timestamp >= self.auctionEnd
75 # Check if this function has already been called
76 assert not self.ended
77
78 # 2. Effects
79 self.ended = True
80
81 # 3. Interaction
82 send(self.beneficiary, self.highestBid)
83
Afficher tout
📋 Copier

Cet exemple devrait vous donner une idée de la syntaxe d'un contrat Vyper. Pour une description plus détaillée des fonctions et des variables, consultez la documentation.

Yul et Yul+

Si vous débutez avec Ethereum et que vous n'avez pas encore jamais codé avec des langages de contrats intelligents, nous vous recommandons de commencer avec Solidity ou Vyper. Intéressez-vous à Yul ou Yul+ seulement une fois que vous êtes familiarisé avec les bonnes pratiques de sécurité pour les contrats intelligents et les spécificités de l'EVM.

Yul

  • Langage intermédiaire pour Ethereum
  • Prends en charge l'EVM et l'eWASM, un assemblage Web au petit goût d'Ethereum, conçu pour être un dénominateur commun utilisable sur les deux plateformes.
  • Excellente cible pour les phases d'optimisation de haut niveau qui peuvent bénéficier à la fois aux plateformes EVM et eWASM.

Yul+

  • Extension de Yul de bas niveau très efficace
  • Initialement conçue pour un contrat de rollup optimisé
  • Yul+ peut être considéré comme une proposition de mise à niveau expérimentale de Yul, qui y ajoute de nouvelles fonctionnalités

Exemple de contrat

Cet exemple simple implémente une fonction puissance. Il peut être compilé en utilisant solc --strict-assembly --bin input.yul et devrait être stocké dans le fichier input.yul.

1{
2 function power(base, exponent) -> result
3 {
4 switch exponent
5 case 0 { result := 1 }
6 case 1 { result := base }
7 default
8 {
9 result := power(mul(base, base), div(exponent, 2))
10 if mod(exponent, 2) { result := mul(base, result) }
11 }
12 }
13 let res := power(calldataload(0), calldataload(32))
14 mstore(0, res)
15 return(0, 32)
16}
17
Afficher tout

Si vous avez déjà une bonne expérience en développement de contrats intelligents, vous trouverez ici une implémentation complète ERC20 dans Yul .

Comment choisir

Comme pour tout autre langage de programmation, il s'agit surtout de choisir le bon outil en fonction du travail à effectuer et des préférences personnelles.

Voici quelques éléments à considérer si vous n'en avez encore essayé :

Quels sont les avantages de Solidity ?

  • Si vous débutez, il existe de nombreux tutoriels et outils d'apprentissage. Pour plus d'infos, consultez la page Apprendre en codant.
  • De bons outils de développement sont disponibles.
  • Solidity dispose d'une importante communauté de développeurs, ce qui signifie que vous obtiendrez probablement des réponses à vos questions très rapidement.

Quels sont les avantages de Vyper ?

  • Excellent moyen de commencer pour les développeurs Python qui veulent rédiger des contrats intelligents.
  • Vyper dispose d'un nombre plus restreint de fonctionnalités, ce qui en fait un langage idéal pour un prototypage rapide des idées.
  • Il est conçu de façon à être facile à contrôler et extrêmement lisible pour l'être humain.

Quels sont les avantages de Yul et Yul+ ?

  • Language simple et fonctionnel de bas niveau.
  • Permet de se rapprocher au plus près de l'EVM brute, ce qui peut aider à optimiser l'utilisation du carburant de vos contrats.

Comparaison des langages

Pour des comparaisons de la syntaxe de base, du cycle de vie des contrats, des interfaces, des opérateurs, des structures de données, des fonctions, du flux de contrôle, et plus encore, consultez la page Auditless Solidity & Vyper Cheat Sheet

Complément d'information