Přeskočit na hlavní obsah
Change page

Jazyk chytrých kontraktů

Stránka naposledy aktualizována: 22. října 2025

Jednou z výhod Etherea je, že smart kontrakty lze programovat v relativně uživatelsky přívětivých programovacích jazycích. Pokud máte zkušenosti s Pythonem nebo jakýmkoli jazykem se složenými závorkamiopens in a new tab, můžete najít jazyk se známou syntaxí.

Dva nejaktivnější a nejvíce udržované jazyky jsou:

  • Solidity
  • Vyper

Remix IDE poskytuje komplexní vývojové prostředí pro vytváření a testování kontraktů jak v Solidity, tak ve Vyperu. Vyzkoušejte Remix IDE v prohlížečiopens in a new tab a začněte kódovat.

Zkušenější vývojáři mohou také chtít používat Yul, což je přechodný jazyk pro Ethereum Virtual Machine, nebo Yul+, rozšíření jazyka Yul.

Pokud jste zvědaví a rádi pomáháte testovat nové jazyky, které jsou stále ve fázi intenzivního vývoje, můžete experimentovat s Fe, nově vznikajícím jazykem pro smart kontrakty, který je v současnosti ještě v rané fázi.

Předpoklady

Předchozí znalosti programovacích jazyků, zejména JavaScriptu nebo Pythonu, vám mohou pomoci lépe porozumět rozdílům mezi jazyky pro smart kontrakty. Doporučujeme také, abyste nejprve pochopili koncept smart kontraktů, než se ponoříte do srovnání jazyků. Úvod do chytrých kontraktů.

Solidity

  • Objektově orientovaný, vysoce úrovňový jazyk pro implementaci chytrých kontraktů.
  • Jazyk se složenými závorkami, který je nejvíce ovlivněn jazykem C++.
  • Staticky typovaný (typ proměnné je znám v době kompilace).
  • Podporuje:
    • Dědičnost (můžete rozšiřovat jiné kontrakty).
    • Knihovny (můžete vytvářet opakovaně použitelný kód, který můžete volat z různých kontraktů – podobně jako statické funkce ve statické třídě v jiných objektově orientovaných programovacích jazycích).
    • Komplexní uživatelem definované typy.

Příklad kontraktu

1// SPDX-License-Identifier: GPL-3.0
2pragma solidity >= 0.7.0;
3
4contract Coin {
5 // Klíčové slovo "public" zpřístupňuje proměnné
6 // z ostatních kontraktů
7 address public minter;
8 mapping (address => uint) public balances;
9
10 // Události umožňují klientům reagovat na specifické
11 // změny kontraktu, které deklarujete
12 event Sent(address from, address to, uint amount);
13
14 // Kód konstruktoru se spouští pouze při vytvoření
15 // kontraktu
16 constructor() {
17 minter = msg.sender;
18 }
19
20 // Odešle množství nově vytvořených mincí na adresu
21 // Může být voláno pouze tvůrcem kontraktu
22 function mint(address receiver, uint amount) public {
23 require(msg.sender == minter);
24 require(amount < 1e60);
25 balances[receiver] += amount;
26 }
27
28 // Odešle množství existujících mincí
29 // od jakéhokoli volajícího na adresu
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}
Zobrazit vše

Tento příklad by vám měl poskytnout představu o tom, jaká je syntaxe kontraktů v Solidity. Podrobnější popis funkcí a proměnných naleznete v dokumentaciopens in a new tab.

Vyper

  • Pythonický programovací jazyk
  • Silné typování
  • Malý a srozumitelný kompilátor
  • Efektivní generování bytekódu
  • Úmyslně má méně funkcí než Solidity s cílem učinit kontrakty bezpečnějšími a snáze auditovatelnými. Vyper nepodporuje:
    • Modifikátory
    • Dědičnost
    • Inline sestavení (assembly)
    • Přetěžování funkcí
    • Přetěžování operátorů
    • Rekurzivní volání
    • Nekonečné smyčky
    • Binární pevné body

Pro více informací si přečtěte Vyper rationaleopens in a new tab.

Příklad

1# Otevřená aukce
2
3# Parametry aukce
4
5# Příjemce obdrží peníze od nejvyššího nabízejícího
6
7beneficiary: public(address)
8auctionStart: public(uint256)
9auctionEnd: public(uint256)
10
11# Aktuální stav aukce
12
13highestBidder: public(address)
14highestBid: public(uint256)
15
16# Na konci se nastaví na true, zakáže jakoukoli změnu
17
18ended: public(bool)
19
20# Sledujeme vrácené nabídky, abychom mohli použít vzor výběru
21
22pendingReturns: public(HashMap[address, uint256])
23
24# Vytvoří jednoduchou aukci s `_bidding_time`
25
26# sekundami pro přihazování jménem
27
28# adresy příjemce `_beneficiary`.
29
30@external
31def __init__(_beneficiary: address, _bidding_time: uint256):
32 self.beneficiary = _beneficiary
33 self.auctionStart = block.timestamp
34 self.auctionEnd = self.auctionStart + _bidding_time
35
36# Přihodí do aukce s hodnotou zaslanou
37
38# spolu s touto transakcí.
39
40# Hodnota bude vrácena pouze v případě,
41
42# že aukce nebude vyhrána.
43
44@external
45@payable
46def bid():
47 # Zkontroluje, zda období pro přihazování skončilo.
48 assert block.timestamp < self.auctionEnd
49 # Zkontroluje, zda je nabídka dostatečně vysoká
50 assert msg.value > self.highestBid
51 # Sleduje vrácení peněz předchozímu nejvyššímu nabízejícímu
52 self.pendingReturns[self.highestBidder] += self.highestBid
53 # Sleduje novou nejvyšší nabídku
54 self.highestBidder = msg.sender
55 self.highestBid = msg.value
56
57# Vybere dříve vrácenou nabídku. Vzor výběru (withdraw pattern) se
58
59# zde používá k zamezení bezpečnostního problému. Pokud by byly refundace přímo
60
61# odesílány jako součást bid(), mohl by škodlivý kontrakt blokovat
62
63# tyto refundace a tím zabránit příchodu nových vyšších nabídek.
64
65@external
66def withdraw():
67 pending_amount: uint256 = self.pendingReturns[msg.sender]
68 self.pendingReturns[msg.sender] = 0
69 send(msg.sender, pending_amount)
70
71# Ukončí aukci a pošle nejvyšší nabídku
72
73# příjemci.
74
75@external
76def endAuction():
77 # Je dobrým zvykem strukturovat funkce, které interagují
78 # s jinými kontrakty (tj. volají funkce nebo posílají ether),
79 # do tří fází:
80 # 1. kontrola podmínek
81 # 2. provádění akcí (potenciálně měnících podmínky)
82 # 3. interakce s jinými kontrakty
83 # Pokud jsou tyto fáze smíchány, jiný kontrakt by mohl volat
84 # zpět do aktuálního kontraktu a upravit stav nebo způsobit,
85 # že efekty (vyplacení etheru) budou provedeny vícekrát.
86 # Pokud interně volané funkce zahrnují interakci s externími
87 # kontrakty, musí být také považovány za interakci s
88 # externími kontrakty.
89
90 # 1. Podmínky
91 # Zkontroluje, zda bylo dosaženo konce aukce
92 assert block.timestamp >= self.auctionEnd
93 # Zkontroluje, zda tato funkce již byla volána
94 assert not self.ended
95
96 # 2. Efekty
97 self.ended = True
98
99 # 3. Interakce
100 send(self.beneficiary, self.highestBid)
Zobrazit vše

Tento příklad by vám měl poskytnout představu o tom, jaká je syntaxe kontraktů ve Vyperu. Podrobnější popis funkcí a proměnných najdete v dokumentaciopens in a new tab.

Yul a Yul+

Pokud jste v Ethereum nováčkem a ještě jste neprogramovali v jazycích pro smart kontrakty, doporučujeme začít se Solidity nebo Vyperem. Na Yul nebo Yul+ se zaměřte až poté, co si osvojíte osvědčené postupy v oblasti bezpečnosti smart kontraktů a specifika práce s EVM.

Yul

  • Pokročilý jazyk pro Ethereum.
  • Podporuje EVM a Ewasmopens in a new tab, což je varianta WebAssembly pro Ethereum, a je navržen tak, aby byl použitelným společným jmenovatelem obou platforem.
  • Dobrá volba pro optimalizační fáze na vyšší úrovni, které mohou mít stejný přínos jak pro platformy EVM, tak pro Ewasm.

Yul+

  • Nízkoúrovňové, vysoce efektivní rozšíření Yulu.
  • Původně navrženo pro kontrakt optimistického rollupu.
  • Yul+ lze považovat za experimentální návrh upgradu Yul, který do něj přidává nové funkce.

Příklad kontraktu

Následující jednoduchý příklad implementuje funkci mocniny. Lze jej zkompilovat pomocí solc --strict-assembly --bin input.yul. Příklad by měl být uložen v souboru 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}
Zobrazit vše

Pokud již máte se smart kontrakty bohaté zkušenosti, úplnou implementaci ERC20 v jazyce Yul naleznete zdeopens in a new tab.

Fe

  • Staticky typovaný jazyk pro Virtuální stroj Etherea (EVM).
  • Inspirován jazyky Python a Rust.
  • Cílem je, aby byl snadno naučitelný – i pro vývojáře, kteří jsou v ekosystému Ethereum noví.
  • Vývoj Fe je stále v raných fázích, první alfa verze jazyka byla vydána v lednu 2021.

Příklad kontraktu

Následuje jednoduchý kontrakt implementovaný v jazyce 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
Zobrazit vše

Jak si vybrat

Stejně jako u jakéhokoli jiného programovacího jazyka jde především o výběr správného nástroje pro daný úkol a o osobní preference.

Uvádíme několik věcí, které byste měli zvážit, pokud jste ještě žádný z jazyků nezkusili:

Co je skvělé na Solidity?

  • Pokud jste začátečník, najdete mnoho tutoriálů a vzdělávacích nástrojů. Více se o tom dozvíte v sekci Učte se kódováním.
  • K dispozici je dobrá sada nástrojů pro vývojáře.
  • Solidity má velkou vývojářskou komunitu, což znamená, že na případné otázky pravděpodobně najdete odpovědi poměrně rychle.

Co je skvělé na Vyperu?

  • Skvělý na začátek pro Python vývojáře, kteří chtějí psát chytré kontrakty.
  • Vyper má menší počet funkcí, což ho činí skvělým pro rychlé prototypování nápadů.
  • Vyper usiluje o snadnou auditovatelnost a maximální čitelnost pro lidské bytosti.

Co je skvělé na Yul a Yul+?

  • Jednoduchý a funkční nízkoúrovňový jazyk.
  • Umožňuje dostat se mnohem blíže k surovému EVM, což vám může pomoci s optimalizací spotřeby paliva vašich kontraktů.

Srovnání jazyků

Pro srovnání základní syntaxe, životního cyklu kontraktů, rozhraní, operátorů, datových struktur, funkcí, řízení toku a dalšího se podívejte na tento tahák od Auditlessopens in a new tab

Další čtení

Byl tento článek užitečný?