Ugrás a fő tartalomra
Change page

Okosszerződés nyelvek

Utolsó módosítás: @Satglow(opens in a new tab), 2024. január 18.

Az Ethereum egyik kiváló jellemzője, hogy az okosszerződéseket viszonylag fejlesztőbarát nyelveken lehet programozni. Ha Ön járatos a Pythonban vagy bármilyen kerek zárójeles nyelvben(opens in a new tab), akkor találhat olyan nyelvet, melynek a szintaxisa ismerős lesz.

A két legaktívabb és leginkább karbantartott nyelv:

  • Solidity
  • Vyper

A tapasztaltabb fejlesztők kipróbálhatják a Yul nyelvet, mely egy haladó nyelv az Ethereum virtuális gépre, vagy ennek kiterjesztését, melynek neve Yul+.

Amennyiben Ön kíváncsi típus, és szeret olyan új nyelvek tesztelésében segíteni, amelyek még komoly fejlesztés előtt állnak, akkor fedezze fel a Fe-t, egy kialakulóban lévő okosszerződésnyelvet, amely még gyerekcipőben jár.

Előfeltételek

A programozási nyelvek, különösen a JavaScript vagy a Python korábbi ismerete segíthet az okosszerződés nyelvekben mutatkozó különbségek értelmezésében. Javasoljuk, hogy először értse meg az okosszerződést, mint koncepciót, mielőtt túl mélyre ásna a nyelvi összehasonlításokban. Bevezetés az okosszerződésekbe.

Solidity

  • Objektumorientált, magas szintű nyelv az okosszerződések telepítésére.
  • Kerek zárójeles nyelv, amelyet a leginkább a C++ befolyásolt.
  • Statikusan típusos (a változó típusa ismert az átfordítási időben).
  • A következőket támogatja:
    • Öröklődés (kiterjeszthet más szerződéseket).
    • Könyvtárak (újrafelhasználható kódot írhat, melyet meghívhat különböző szerződésekből – mint a statikus függvényeket statikus osztályokban más objektumorientált programozási nyelveken).
    • Komplex, felhasználó által definiált típusok.

Példaszerződés

1// SPDX-License-Identifier: GPL-3.0
2pragma solidity >= 0.7.0;
3
4contract Coin {
5 // A "public" kulcsszó a változókat
6 // elérhetővé teszi más szerződések számára
7 address public minter;
8 mapping (address => uint) public balances;
9
10 // Az események lehetővé teszik, hogy a kliensek
11 // általad deklarált szerződés változásokra reagáljanak
12 event Sent(address from, address to, uint amount);
13
14 // A konstruktor csak a szerződés létrehozásakor
15 // fut le
16 constructor() {
17 minter = msg.sender;
18 }
19
20 // Az újonnan létrehozott tokeneket elküldi egy címre
21 // Csak a szerződés létrehozó hívhatja meg
22 function mint(address receiver, uint amount) public {
23 require(msg.sender == minter);
24 require(amount < 1e60);
25 balances[receiver] += amount;
26 }
27
28 // Elküld valamennyi létező tokent
29 // bármely hívótól egy címre
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}
Összes megjelenítése
Másolás

Ez a példa azt mutathatja meg Önnek, hogyan néz ki a Solidity szerződés szintaxisa. A függvények és a változók részletesebb leírásáért tekintse meg a dokumentációt(opens in a new tab).

Vyper

  • Pythonikus programozási nyelv
  • Erősen típusos
  • Kicsi és érthető fordító kód
  • Hatékony bájtkód-generálás
  • Szándékosan kevesebb elemmel rendelkezik, mint a Solidity, azzal a céllal, hogy a szerződések biztonságosabbak és könnyebben auditálhatóak legyenek. A Vyper nem támogatja a következőket:
    • Módosítókat (modifier)
    • Öröklést
    • Soron belüli assembly
    • Függvénytúlterhelés
    • Operátortúlterhelés
    • Rekurzív hívás
    • Végtelen hosszú ciklusok
    • Bináris fix pontok

További információkért tekintse meg a Vyper magyarázatát(opens in a new tab).

Példa

1# Nyílt Aukció
2
3# Aukció paraméterek
4# A kedvezményezett pénzt kap a legnagyobb licitálótól
5beneficiary: public(address)
6auctionStart: public(uint256)
7auctionEnd: public(uint256)
8
9# Az aukció jelenlegi állapota
10highestBidder: public(address)
11highestBid: public(uint256)
12
13# Legyen igaz a végén, bármely változást elutasít
14ended: public(bool)
15
16# Számontartja a visszafizetett liciteket, így követni tudjuk a kiutalási mintát
17pendingReturns: public(HashMap[address, uint256])
18
19# Egy egyszerű aukció létrehozása `_bidding_time`
20# másodpercnyi licit idővel a kedvezményezett cím
21# `_beneficiary` nevében.
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# Licitálás az aukción
29# a tranzakcióval küldött értékkel.
30# Az érték csak akkor kerül visszautalásra
31# ha az aukció nincs megnyerve.
32@external
33@payable
34def bid():
35 # Ellenőrzi, hogy a licit idő véget ért-e már.
36 assert block.timestamp < self.auctionEnd
37 # Ellenőrzi, hogy elég magas-e a licit
38 assert msg.value > self.highestBid
39 # Nyomonköveti az előző legmagasabb licit visszatérítését
40 self.pendingReturns[self.highestBidder] += self.highestBid
41 # Nyomonköveti a legmagasabb licitet
42 self.highestBidder = msg.sender
43 self.highestBid = msg.value
44
45# Kiutalja az előzőleg visszatérített licitet. A kiutalási mintát használjuk itt,
46# hogy elkerüljünk egy biztonsági rést. Ha a visszatérítés közvetlenül
47# a bid() része lenne, egy ártalmas licit szerződés blokkolhatná
48# ezeket a visszatérítéseket, így blokkolná a magasabb bejövő liciteket.
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# Vége az aukciónak és elküldi a legmagasabb licitet
56# a kedvezményezettnek.
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. feltételek ellenőrzése
63 # 2. akció végrehajtás (potenciálisan megváltoztatja a feltételeket)
64 # 3. interakció más szerződésekkel
65 # Ha ezt a sorrendet felcseréljük, akkor más szerződés visszahívhat
66 # a jelenlegi szerződésbe és módosíthatja az állapotot vagy
67 # többszörösen elvégzett műveletet eredményezhet (ether kifizetés).
68 # Ha a belsőleg meghívott függvény külső szerződéssel történő
69 # interakciót tartalmaz, akkor azokat is külső szerződéssel történő
70 # interakcióként kell kezelni.
71
72 # 1. Feltételek
73 # Ellenőrzi, hogy elértük-e az aukció végét
74 assert block.timestamp >= self.auctionEnd
75 # Ellenőrzi, hogy függvény meg lett-e már hívva
76 assert not self.ended
77
78 # 2. Hatások
79 self.ended = True
80
81 # 3. Interakció
82 send(self.beneficiary, self.highestBid)
Összes megjelenítése
Másolás

Ez a példa megmutathatja Önnek, hogyan néz ki a Vyper szerződés szintaxisa. A függvények és a változók részletesebb leírásáért tekintse meg a dokumentációt(opens in a new tab).

Yul és Yul+

Ha Önnek új az Ethereum és nem programozott okosszerződésnyelveken, akkor azt javasoljuk, hogy kezdjen először a Solidity-vel és a Vyperrel. Csak akkor kezdjen bele a Yul vagy Yul+ nyelvekbe, ha már ismeri az okosszerződésre vonatkozó biztonsági gyakorlatokat és az EVM-mel kapcsolatos munka részleteit.

Yul

  • Haladó nyelv Ethereumra.
  • Támogatja az EVM-et és az Ewasm-ot(opens in a new tab), amely egy Ethereummal fűszerezett WebAssembly, és amelyet a két platform közös nevezőjének terveztek.
  • Jó cél a magas szintű optimizációs szinteknek, melyek az EVM és Ewasm platformokból egyaránt tudnak profitálni.

Yul+

  • A Yul alacsony szintű, nagy hatékonyságú kiterjesztése.
  • Eredetileg az optimista összesítéses szerződésként fejlesztették ki.
  • A Yul+ egy kísérleti fejlesztési javaslatként is tekinthető, melyhez új funkciók tartoznak.

Példa szerződés

Az alábbi egyszerű példa egy hatványfüggvényt implementál. A solc --strict-assembly --bin input.yul használatával lehet befordítani. Ezt a példát az input.yul fájlnak kell tartalmaznia.

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}
Összes megjelenítése

Ha már nagy tapasztalatra tett szert az okosszerződésekkel kapcsolatban, akkor a teljes ERC20 implementáció Yul-ban itt érhető el(opens in a new tab).

Fe

  • Statikusan típusos nyelv az Ethereum virtuális géphez (EVM).
  • A Python és a Rust inspirálta.
  • Lényege, hogy könnyen tanulható, még azoknak a fejlesztőknek is, akiknek új az Ethereum ökoszisztémája.
  • A Fe fejlesztése még nagyon korai szakaszban tart, az alfa kiadása 2021. januárban történt.

Példa szerződés

Ez a példa egy egyszerű szerződés Fe nyelven telepítve.

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
Összes megjelenítése

Hogyan válasszunk

Mint minden más programozási nyelvnél, itt is leginkább a megfelelő eszköz kiválasztása a megfelelő munkához, valamint a személyes preferenciák döntenek.

Íme néhány szempont, amelyet érdemes figyelembe venni, ha még nem próbálta egyik nyelvet sem:

Mi a jó a Solidity-ben?

  • A kezdőknek sok útmutató és tanulási anyag áll rendelkezésükre. További anyagért látogasson el a Tanulás kódolással című részhez.
  • Remek fejlesztői eszközök érhetők el.
  • A Solidity-nek kiterjedt a fejlesztői közössége, ami azt jelenti, hogy nagy valószínűséggel gyorsan választ kap a kérdéseire.

Mi a jó a Vyperben?

  • Nagyszerű módszer a Python fejlesztők számára az első okosszerződések megírására.
  • A Vyper kevesebb funkcióval rendelkezik, így kiválóan alkalmas arra, hogy az ötleteiből gyorsan prototípust készítsen.
  • A Vyper célja, hogy könnyen auditálható és az emberek számára olvasható legyen.

Mi a jó a Yul és a Yul+ nyelvekben?

  • Egyszerűsített és funkcionális alacsony szintű nyelv.
  • Közelebb enged a nyers EVM-hez, így Ön könnyebben tudja a szerződések gázfelhasználását optimalizálni.

Nyelv-összehasonlítások

Az alapvető szintaxis, szerződés-életciklus, interfészek, operátorok, adatszerkezetek, függvények, control flow és további szempontok alapján történő összehasonlításért olvassa el a Puska az Auditless-től(opens in a new tab) című cikket

További olvasnivaló

Hasznosnak találta a cikket?