Linguaggi dei contratti intelligenti
Ultima modifica: @Herbie_23(opens in a new tab), 17 giugno 2024
Uno degli aspetti positivi di Ethereum è che i contratti intelligenti sono programmabili usando linguaggi relativamente comodi per gli sviluppatori. Se hai esperienza con Python o altri linguaggi a parentesi graffa(opens in a new tab), troverai un linguaggio con una sintassi familiare.
I due linguaggi più attivi e gestiti sono:
- Solidity
- Vyper
Gli sviluppatori più esperti potrebbero prendere in considerazione anche Yul, un linguaggio intermedio per la macchina virtuale Ethereum, oppure Yul +, un'estensione di Yul.
Se sei curioso e vorresti aiutare a testare nuovi linguaggi ancora in via di sviluppo, puoi sperimentare con Fe, un linguaggio emergente nel campo dei contratti intelligenti, correntemente ai suoi inizi.
Prerequisiti
Una conoscenza pregressa dei linguaggi di programmazione, specialmente JavaScript o Python, può aiutarti a comprendere le differenze tra i linguaggi dei contratti intelligenti. Ti consigliamo inoltre di approfondire i contratti intelligenti, prima di approfondire i confronti dei vari linguaggi. Introduzione ai contratti intelligenti.
Solidity
- Linguaggio d'alto livello orientato agli oggetti per l'implementazione dei contratti intelligenti.
- Linguaggio a parentesi graffa profondamente influenzato da C++.
- Statico (il tipo di una variabile è noto al momento della compilazione).
- Supporta:
- Ereditarietà (puoi estendere altri contratti).
- Librerie (puoi creare del codice riutilizzabile che puoi chiamare da contratti diversi, come le funzioni statiche in una classe statica in altri linguaggi di programmazione orientati agli oggetti).
- Tipi complessi, definiti dall'utente.
Link importanti
- Documentazione(opens in a new tab)
- Portale del Linguaggio di Solidity(opens in a new tab)
- Solidity per Esempio(opens in a new tab)
- GitHub(opens in a new tab)
- Solidity Gitter Chatroom(opens in a new tab) collegato a Solidity Matrix Chatroom(opens in a new tab)
- Cheat Sheet(opens in a new tab)
- Solidity Blog(opens in a new tab)
- Twitter di Solidity(opens in a new tab)
Esempio di contratto
1// SPDX-License-Identifier: GPL-3.02pragma solidity >= 0.7.0;34contract Coin {5 // La parola chiave "public" rende le variabili6 // accessibili da altri contratti7 address public minter;8 mapping (address => uint) public balances;910 // Gli eventi consentono ai client di reagire a specifiche11 // modifiche ai contratti che vengono dichiarate12 event Sent(address from, address to, uint amount);1314 // Il codice del costruttore viene eseguito solo quando il contratto15 // viene creato16 constructor() {17 minter = msg.sender;18 }1920 // Invia una quantità di monete appena create a un indirizzo21 // Può essere chiamato solo dal creatore del contratto22 function mint(address receiver, uint amount) public {23 require(msg.sender == minter);24 require(amount < 1e60);25 balances[receiver] += amount;26 }2728 // Invia una quantità di monete esistenti29 // da qualsiasi chiamante a un indirizzo30 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}Mostra tuttoCopia
Questo esempio dà un'idea della sintassi di un contratto in Solidity. Per una descrizione più dettagliata di funzioni e variabili, consulta la documentazione(opens in a new tab).
Vyper
- Linguaggio di programmazione Pythonic
- Tipizzazione forte
- Codice del compilatore contenuto e comprensibile
- Generazione di bytecode efficiente
- Contiene deliberatamente meno funzionalità di Solidity, mirando a rendere i contratti più sicuri e facili da xcontcontrollare. Vyper non supporta:
- Modificatori
- Ereditarietà
- Assemblaggio in linea
- Sovraccarico della funzione
- Sovraccarico dell'operatore
- Chiamate ricorsive
- Cicli di lunghezza infinita
- Punti fissi binari
Per ulteriori informazioni, consulta la logica di Vyper(opens in a new tab).
Link importanti
- Documentazione(opens in a new tab)
- Vyper per Esempio(opens in a new tab)
- Più Vyper per Esempio(opens in a new tab)
- GitHub(opens in a new tab)
- Chat Discord della community di Vyper(opens in a new tab)
- Cheat Sheet(opens in a new tab)
- Quadro di sviluppo dei contratti intelligenti e strumenti per Vyper
- VyperPunk: impara a proteggere e hackerare i contratti intelligenti di Vyper(opens in a new tab)
- VyperExamples: Esempi di vulnerabilità di Vyper(opens in a new tab)
- Hub di Vyper per lo sviluppo(opens in a new tab)
- Esempi dei migliori contratti intelligenti di Vyper(opens in a new tab)
- Fantastiche risorse curate di Vyper(opens in a new tab)
Esempio
1# Apertura asta23# Parametri d'asta4# Il beneficiario riceve denaro dal miglior offerente5beneficiary: public(address)6auctionStart: public(uint256)7auctionEnd: public(uint256)89# Stato attuale dell'asta10highestBidder: public(address)11highestBid: public(uint256)1213# Imposta a true alla fine per non permettere più modifiche14ended: public(bool)1516# Tiene traccia delle offerte rimborsate in modo da poter seguire il modello di prelievo17pendingReturns: public(HashMap[address, uint256])1819# Crea una semplice asta con `_bidding_time`20# tempo di offerta in secondi per conto21# dell'indirizzo del beneficiario `_beneficiary`.22@external23def __init__(_beneficiary: address, _bidding_time: uint256):24 self.beneficiary = _beneficiary25 self.auctionStart = block.timestamp26 self.auctionEnd = self.auctionStart + _bidding_time2728# Offerta sull'asta con il valore inviato29# insieme a questa transazione.30# Il valore sarà rimborsato solo se l'asta31# non viene vinta.32@external33@payable34def bid():35 # Controlla se il periodo di offerta è finito.36 assert block.timestamp < self.auctionEnd37 # Verifica se l'offerta è abbastanza alta38 assert msg.value > self.highestBid39 # Tiene traccia del rimborso all'offerente più alto precedente40 self.pendingReturns[self.highestBidder] += self.highestBid41 # Tiene traccia della nuova offerta più alta42 self.highestBidder = msg.sender43 self.highestBid = msg.value4445# Preleva un'offerta precedentemente rimborsata. Il modello di prelievo è46# utilizzato qui per evitare un problema di sicurezza. Se i rimborsi venissero inviati direttamente47# come parte di bid(), un contratto di offerta malevolo potrebbe bloccarli48# e quindi bloccare le nuove offerte più alte in arrivo.49@external50def withdraw():51 pending_amount: uint256 = self.pendingReturns[msg.sender]52 self.pendingReturns[msg.sender] = 053 send(msg.sender, pending_amount)5455# Termina l'asta e invia l'offerta più alta56# al beneficiario.57@external58def endAuction():59 # It is a good guideline to structure functions that interact60 # with other contracts (i.e. they call functions or send ether)61 # into three phases:62 # 1. controllo delle condizioni63 # 2. esecuzione delle azioni (potenzialmente modificando le condizioni)64 # 3. interazione con altri contratti65 # Se queste fasi sono mischiate, l'altro contratto potrebbe eseguire66 # nuove chiamate al contratto corrente e modificare lo stato o causare67 # effetti (pagamento di ether) da eseguire più volte.68 # Se le funzioni chiamate internamente includono l'interazione con contratti esterni69 # devono essere considerate anche interazioni con70 # contratti esterni.7172 # 1. Condizioni73 # Controlla se la fine dell'asta è stata raggiunta74 assert block.timestamp >= self.auctionEnd75 # Verifica se questa funzione è già stata chiamata76 assert not self.ended7778 # 2. Effetti79 self.ended = True8081 # 3. Interazione82 send(self.beneficiary, self.highestBid)Mostra tuttoCopia
Questo esempio dovrebbe darti un'idea della sintassi di un contratto in Vyper. Per una descrizione più dettagliata di funzioni e variabili, consulta la documentazione(opens in a new tab).
Yul e Yul+
Se non hai esperienza con Ethereum e non hai ancora programmato con alcun linguaggio dei contratti intelligenti, consigliamo di iniziare con Solidity o Vyper. Considera Yul o Yul+ solo quando hai acquisito familiarità con le migliori pratiche di sicurezza per i contratti intelligenti e con le specifiche per l'utilizzo dell'EVM.
Yul
- Linguaggio intermedio per Ethereum.
- Supporta l'EVM ed Ewasm(opens in a new tab), un WebAssembly orientato a Ethereum, progettato per essere un denominatore comune utilizzabile di entrambe le piattaforme.
- Buona soluzione per le fasi di ottimizzazione di alto livello che possono essere utili per entrambe le piattaforme, EVM ed eWASM.
Yul+
- Un'estensione a Yul molto efficiente e di basso livello.
- Inizialmente progettata per il contratto di un rollup ottimistico.
- Yul+ può essere considerato come una proposta di upgrade sperimentale a Yul che aggiunge nuove funzionalità.
Link importanti
- Documentazione di Yul(opens in a new tab)
- Documentazione di Yul+(opens in a new tab)
- Playground di Yul+(opens in a new tab)
- Post Introduttivo di Yul+(opens in a new tab)
Esempio di contratto
Il seguente semplice esempio implementa una funzione di potenza. Può essere compilato usando solc --strict-assembly --bin input.yul
. L'esempio dovrebbe esser archiviato nel file input.yul.
1{2 function power(base, exponent) -> result3 {4 switch exponent5 case 0 { result := 1 }6 case 1 { result := base }7 default8 {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}Mostra tutto
Se hai già una buona esperienza coi contratti intelligenti, puoi trovare qui(opens in a new tab) un'implementazione completa di ERC-20 su Yul.
Fe
- Linguaggio statico per la Macchina Virtuale di Ethereum (EVM).
- Ispirato da Python e Rust.
- Mira a esser facile da imparare, anche per sviluppatori nuovi all'ecosistema di Ethereum.
- Lo sviluppo di Fe è ancora alle fasi iniziali e a gennaio 2021 è stata rilasciata la versione alfa del linguaggio.
Link importanti
- GitHub(opens in a new tab)
- Annuncio di Fe(opens in a new tab)
- Tabella di marcia 2021 di Fe(opens in a new tab)
- Chat Discord di Fe(opens in a new tab)
- Twitter di Fe(opens in a new tab)
Esempio di contratto
Il seguente è un contratto semplice implementato in Fe.
1type BookMsg = bytes[100]23contract GuestBook:4 pub guest_book: map<address, BookMsg>56 event Signed:7 book_msg: BookMsg89 pub def sign(book_msg: BookMsg):10 self.guest_book[msg.sender] = book_msg1112 emit Signed(book_msg=book_msg)1314 pub def get_msg(addr: address) -> BookMsg:15 return self.guest_book[addr].to_mem()16Mostra tutto
Come scegliere
Come per ogni altro linguaggio di programmazione, si tratta principalmente di scegliere lo strumento adatto al lavoro da compiere, nonché sulle preferenze personali.
Ecco alcune cose da considerare se non hai ancora provato i vari linguaggi:
Quali vantaggi offre Solidity?
- Se sei un principiante, esistono molti tutorial e strumenti di apprendimento. Visualizza di più nella sezione Impara Programmando.
- Buoni strumenti per sviluppatori disponibili.
- Solidity ha un'ampia community di sviluppatori, quindi probabilmente troverai le risposte alle tue domande abbastanza rapidamente.
Quali vantaggi offre Vyper?
- Ottimo modo per iniziare per gli sviluppatori di Python che vogliono scrivere contratti intelligenti.
- Vyper ha un numero minore di funzionalità che lo rendono perfetto per la prototipazione rapida di idee.
- Vyper mira a facilitare il controllo del codice e a renderlo il più leggibile possibile.
Quali vantaggi offrono Yul e Yul+?
- Linguaggio di basso livello, semplicistico e funzionale.
- Consente di avvicinarsi all'EVM grezza, aiutando a ottimizzare l'uso di gas dei tuoi contratti.
Confronti tra linguaggi
Per confrontare la sintassi di base, la durata del contratto, le interfacce, gli operatori, le strutture di dati, le funzioni, il flusso di controllo e altro, consulta questo contenuto riassuntivo di Auditless(opens in a new tab)
Ulteriori letture
- Libreria di Contratti in Solidity di OpenZeppelin(opens in a new tab)
- Solidity per Esempio(opens in a new tab)