Salt la conținutul principal
Change page

Limbaje pentru contractele inteligente

Ultima modificare: @nicklcanada(opens in a new tab), 9 ianuarie 2024

Un aspect important despre Ethereum este că puteţi programa contractele inteligente folosind limbaje relativ uşor de utilizat de către dezvoltatori. Dacă aveţi experiență cu Python sau cu orice limbaj de programare cu acolade(opens in a new tab), puteţi găsi un limbaj a cărui sintaxă o cunoaşteţi.

Cele mai active și acceptate două limbaje sunt:

  • Solidity
  • Vyper

Dezvoltatorii mai experimentați ar putea dori să utilizeze şi Yul, un limbaj intermediar pentru Mașina virtuală Ethereum sau Yul +, o extensie pentru Yul.

Dacă sunteţi curios și vă place să ajutaţi la testarea unor limbaje noi pentru care procesul de dezvoltare este departe de a fi finalizat, puteţi experimenta utilizarea Fe, un limbaj emergent al contractelor inteligente, care se află încă la începuturi.

Condiții prealabile

Dacă aveţi deja cunoştinţe de limbaje de programare, în special JavaScript sau Python, aceasta vă poate ajuta să înțelegeţi diferențele între limbajele contractelor inteligente. De asemenea, vă recomandăm să înțelegeţi conceptul de bază al contractelor inteligente înainte de a avansa în procesul de comparaţie a limbajelor între ele. Introducere despre contractele inteligente.

Solidity

  • Un limbaj de nivel înalt, orientat pe obiecte, pentru implementarea contractelor inteligente.
  • Limbajul cu acolade care a fost influențat cel mai profund de C++.
  • Static tipizat (tipul unei variabile este cunoscut în momentul compilării).
  • Acceptă:
    • Moștenirea (puteţi extinde alte contracte).
    • Biblioteci (puteţi crea cod reutilizabil, pe care îl puteţi apela din diferite contracte – cum ar fi funcțiile statice dintr-o clasă statică în alte limbaje de programare orientate pe obiecte).
    • Tipuri complexe definite de utilizator.

Exemplu de contract

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}
Afișează tot
Copiați

Acest exemplu ar trebui să vă dea o idee despre sintaxa contractului Solidity. Pentru o descriere mai detaliată a funcțiilor și variabilelor, consultaţi documentația(opens in a new tab).

Vyper

  • Limbajul de programare Pythonic
  • Tipizare puternică
  • Cod de compilator mic și ușor de înțeles
  • În mod deliberat are mai puține caracteristici decât Solidity, în scopul de a creşte securitatea contractelor şi a le facilita auditarea. Vyper nu acceptă:
    • Modificatorii
    • Moștenirea
    • Asamblarea în linie
    • Supraîncărcarea funcțiilor
    • Supraîncărcarea operatorilor
    • Apelurile recursive
    • Buclele infinite
    • Punctele fixe binare

Pentru mai multe informații, citiţi raționamentul pentru Vyper(opens in a new tab).

Exemplu

1# Deschide licitația
2
3# Parametri de licitație
4# Beneficiarul primește bani de la cel mai mare ofertant
5beneficiary: public(address)
6auctionStart: public(uint256)
7auctionEnd: public(uint256)
8
9# Starea actuală a licitației
10highestBidder: public(address)
11highestBid: public(uint256)
12
13# Setat la „true” la sfârșit, interzice orice modificare
14ended: public(bool)
15
16# Ține evidența ofertelor rambursate, astfel încât să putem urma modelul de retragere
17pendingReturns: public(HashMap[address, uint256])
18
19# Creează o licitație simplă cu `_bidding_time`
20# în secunde în numele
21# beneficiarului adresei `_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# Licitează la licitație cu valoarea trimisă
29# împreună cu această tranzacție.
30# Valoarea va fi rambursată numai dacă
31# licitația nu este câștigată.
32@external
33@payable
34def bid():
35 # Verifică dacă perioada de licitare a trecut.
36 assert block.timestamp < self.auctionEnd
37 # Verifică dacă suma licitată este suficient de mare
38 assert msg.value > self.highestBid
39 # Urmărește rambursarea pentru cel mai înalt ofertant anterior
40 self.pendingReturns[self.highestBidder] += self.highestBid
41 # Urmărește o nouă ofertă ridicată
42 self.highestBidder = msg.sender
43 self.highestBid = msg.value
44
45# Retrage o ofertă rambursată anterior. Modelul de retragere este
46# folosit aici pentru a evita o problemă de securitate. Dacă rambursările au fost direct
47# trimise ca parte a ofertei „bid()", un contract de licitare rău intenționat ar putea bloca
48# aceste rambursări și astfel bloca intrarea noilor sume mai mari licitate.
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# Încheie licitația și trimiteți cea mai mare ofertă
56# către beneficiar.
57@external
58def endAuction():
59 # o recomandare bună ar fi să structuraţi funcțiile care interacționează
60 # cu alte contracte (adică apelează funcții sau trimit ether)
61 # în trei faze:
62 # 1. verificarea condițiilor
63 # 2. efectuarea de acțiuni (condiții potențial schimbătoare)
64 # 3. interacționarea cu alte contracte
65 # Dacă aceste faze sunt amestecate, celălalt contract ar putea apela
66 # înapoi contractul actual și modifica starea sau cauza
67 # efecte ca (plata eterului) care s-ar face de mai multe ori.
68 # Dacă funcțiile numite „internaly” includ interacțiunea cu contracte
69 # externe, trebuie de asemenea să fie considerate interacțiuni cu
70 # contractele externe.
71
72 # 1. Condiții
73 # Verifică dacă a fost atinsă ora de încheiere a licitației
74 assert block.timestamp >= self.auctionEnd
75 # Verifică dacă această funcție a fost deja chemată
76 assert not self.ended
77
78 # 2. Efecte
79 self.ended = True
80
81 # 3. Interacțiune
82 send(self.beneficiary, self.highestBid)
Afișează tot
Copiați

Acest exemplu ar trebui să vă dea o idee despre sintaxa contractului Vyper. Pentru o descriere mai detaliată a funcțiilor și variabilelor, vedeţi documentația(opens in a new tab).

Yul și Yul+

Dacă nu aţi mai folosit Ethereum și încă nu ați scris coduri cu limbaje de contracte inteligente, vă recomandăm să începeți cu Solidity sau Vyper. Treceţi la Yul sau Yul+ numai după ce v-aţi familiarizat cu cele mai bune practici pentru securitatea contractelor inteligente și cu specificul de lucru cu EVM.

Yul

  • Limbaj intermediar pentru Ethereum.
  • Acceptă EVM și eWASM(opens in a new tab), un WebAssembly ce aduce a Ethereum, conceput să fie un numitor comun utilizabil pe ambele platforme.
  • Este bine să îl vizăm în etapele de optimizare la nivel înalt, cu avantaje atât pentru platformele EVM, cât și pentru platformele eWASM.

Yul+

  • O extensie de nivel inferior, extrem de eficientă, a Yul.
  • Conceput inițial pentru un contract rolllup optimistic.
  • Yul+ poate fi considerat o propunere experimentală de actualizare a Yul, ce îi adaugă noi funcţionalităţi.

Exemplu de contract

Următorul exemplu simplu implementează o funcție de ridicare la putere. Poate fi compilat folosind solc --strict-assembly --bin input.yul. Exemplul ar trebui să fie stocat în fișierul 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}
Afișează tot

Dacă aveţi deja suficientă experienţă privind contractele inteligente, puteţi găsi o implementare completă ERC20 în Yul aici(opens in a new tab).

Fe

  • Limbaj static tipizat pentru Mașina Virtuală Ethereum (EVM).
  • Inspirat de Python și Rust.
  • Scopul este de a fi ușor de învățat -- chiar și pentru dezvoltatorii care nu au mai folosit ecosistemul Ethereum.
  • Dezvoltarea Fe se află încă în faza incipientă, limbajul având o versiune alfa lansată în ianuarie 2021.

Exemplu de contract

Iată un contract simplu implementat în Fe.

1type BookMsg = bytes[100]
2
3contract GuestBook:
4 pub guest_book: map<address, BookMsg>
5
6 event Signed:
7 book_msg: BookMsg
8
9 pub def sign(book_msg: BookMsg):
10 self.guest_book[msg.sender] = book_msg
11
12 emit Signed(book_msg=book_msg)
13
14 pub def get_msg(addr: address) -> BookMsg:
15 return self.guest_book[addr].to_mem()
16
Afișează tot

Cum să alegeţi

La fel ca în orice alt limbaj de programare, este vorba atât de alegerea unui instrument potrivit pentru proiect, cât în funcţie de preferințele personale.

Iată câteva lucruri de luat în considerare, dacă nu aţi mai folosit niciunul dintre limbaje:

Ce este excelent la Solidity?

  • Dacă sunteţi începător, există multe tutoriale și instrumente de învățare. Aflaţi mai multe informații despre aceasta în secțiunea Învațaţi scriind cod.
  • Sunt disponibile instrumente bune pentru dezvoltatori.
  • Solidity are o comunitate mare de dezvoltatori, ceea ce înseamnă că veţi găsi răspunsuri la întrebările dvs. cel mai probabil destul de repede.

Ce este excelent la Vyper?

  • O modalitate excelentă de a începe pentru dezvoltatorii Python care doresc să scrie contracte inteligente.
  • Vyper are un număr mai mic de funcţionalităţi, ceea ce îl face excelent pentru crearea unor idei de prototip.
  • Vyper își propune să fie ușor de auditat și extrem de ușor de citit de către oameni.

Ce este excelent la Yul și Yul+?

  • Limbaj simplist și funcțional la nivel inferior.
  • Permite o apropiere mai bună de EVM-ul brut, ceea ce poate ajuta la optimizarea consumului de gaz din contractele dvs.

Comparații între limbaje

Pentru a vedea comparații ale sintaxei de bază, ciclul de viață al contractului, interfețele, operatorii, structurile de date, funcțiile, fluxul de control și multe altele, consultaţi acest Cheat Sheet creat de Auditless(opens in a new tab)

Referințe suplimentare

A fost util acest articol?