Jazyky pro chytré kontrakty
Skvělou vlastností Etherea je, že chytré kontrakty lze programovat pomocí jazyků, které jsou pro vývojáře poměrně přívětivé. Pokud máte zkušenosti s Pythonem nebo jakýmkoli jazykem se složenými závorkami (opens in a new tab), najdete zde jazyk se známou syntaxí.
Dva nejaktivnější a nejudržovanější jazyky jsou:
- Solidity
- Vyper
Remix IDE poskytuje komplexní vývojové prostředí pro vytváření a testování kontraktů v Solidity i Vyperu. Vyzkoušejte Remix IDE v prohlížeči (opens in a new tab) a začněte programovat.
Zkušenější vývojáři mohou také chtít použít Yul, mezijazyk pro Ethereum Virtual Machine, nebo Yul+, což je 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 chytré kontrakty, který je v současné době stále v plenkách.
Předpoklady
Předchozí znalost programovacích jazyků, zejména JavaScriptu nebo Pythonu, vám může pomoci pochopit rozdíly v jazycích pro chytré kontrakty. Než se ponoříte příliš hluboko do srovnávání jazyků, doporučujeme vám také porozumět chytrým kontraktům jako konceptu. Úvod do chytrých kontraktů.
Solidity
- Objektově orientovaný vysokoúrovňový jazyk pro implementaci chytrých kontraktů.
- Jazyk se složenými závorkami, který byl 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 znovupoužitelný kód, který lze 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živatelsky definované typy.
Důležité odkazy
- Dokumentace (opens in a new tab)
- Portál jazyka Solidity (opens in a new tab)
- Solidity na příkladech (opens in a new tab)
- GitHub (opens in a new tab)
- Chatovací místnost Solidity na Gitteru (opens in a new tab) propojená s chatovací místností Solidity na Matrixu (opens in a new tab)
- Tahák (opens in a new tab)
- Blog o Solidity (opens in a new tab)
- Twitter Solidity (opens in a new tab)
Příklad kontraktu
// SPDX-License-Identifier: GPL-3.0
pragma solidity >= 0.7.0;
contract Coin {
// Klíčové slovo "public" činí proměnné
// přístupnými z jiných kontraktů
address public minter;
mapping (address => uint) public balances;
// Události umožňují klientům reagovat na specifické
// změny kontraktu, které deklarujete
event Sent(address from, address to, uint amount);
// Kód konstruktoru se spustí pouze tehdy, když je kontrakt
// vytvořen
constructor() {
minter = msg.sender;
}
// Odešle množství nově vytvořených mincí na adresu
// Může být zavoláno pouze tvůrcem kontraktu
function mint(address receiver, uint amount) public {
require(msg.sender == minter);
require(amount < 1e60);
balances[receiver] += amount;
}
// Odešle množství existujících mincí
// od jakéhokoli volajícího na adresu
function send(address receiver, uint amount) public {
require(amount <= balances[msg.sender], "Insufficient balance.");
balances[msg.sender] -= amount;
balances[receiver] += amount;
emit Sent(msg.sender, receiver, amount);
}
}
Tento příklad by vám měl poskytnout představu o tom, jak vypadá syntaxe kontraktu v Solidity. Podrobnější popis funkcí a proměnných najdete v dokumentaci (opens in a new tab).
Vyper
- Programovací jazyk v pythonovském stylu
- Silné typování
- Malý a srozumitelný kód kompilátoru
- Efektivní generování bajtkódu
- Záměrně 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
- Vložený (inline) assembly
- Přetěžování funkcí
- Přetěžování operátorů
- Rekurzivní volání
- Smyčky nekonečné délky
- Binární pevnou řádovou čárku
Pro více informací si přečtěte zdůvodnění návrhu jazyka Vyper (opens in a new tab).
Důležité odkazy
- Dokumentace (opens in a new tab)
- Vyper na příkladech (opens in a new tab)
- Další příklady ve Vyperu (opens in a new tab)
- GitHub (opens in a new tab)
- Komunitní chat Vyperu na Discordu (opens in a new tab)
- Tahák (opens in a new tab)
- Frameworky a nástroje pro vývoj chytrých kontraktů ve Vyperu
- VyperPunk - naučte se zabezpečit a hackovat chytré kontrakty ve Vyperu (opens in a new tab)
- Vyper Hub pro vývoj (opens in a new tab)
- Nejlepší příklady chytrých kontraktů ve Vyperu (opens in a new tab)
- Awesome Vyper – kurátorované zdroje (opens in a new tab)
Příklad
# Otevřená aukce
# Parametry aukce
# Příjemce obdrží peníze od účastníka s nejvyšší nabídkou
beneficiary: public(address)
auctionStart: public(uint256)
auctionEnd: public(uint256)
# Aktuální stav aukce
highestBidder: public(address)
highestBid: public(uint256)
# Na konci nastaveno na true, znemožní jakoukoli změnu
ended: public(bool)
# Udržuje přehled o vrácených nabídkách, abychom mohli následovat vzor výběru
pendingReturns: public(HashMap[address, uint256])
# Vytvoří jednoduchou aukci s dobou pro podávání nabídek `_bidding_time`
# sekund ve prospěch
# adresy příjemce `_beneficiary`.
@external
def __init__(_beneficiary: address, _bidding_time: uint256):
self.beneficiary = _beneficiary
self.auctionStart = block.timestamp
self.auctionEnd = self.auctionStart + _bidding_time
# Přihodí v aukci s hodnotou odeslanou
# společně s touto transakcí.
# Hodnota bude vrácena pouze v případě, že
# aukce není vyhrána.
@external
@payable
def bid():
# Zkontroluje, zda skončilo období pro podávání nabídek.
assert block.timestamp < self.auctionEnd
# Zkontroluje, zda je nabídka dostatečně vysoká
assert msg.value > self.highestBid
# Zaznamená vrácení peněz pro předchozího účastníka s nejvyšší nabídkou
self.pendingReturns[self.highestBidder] += self.highestBid
# Zaznamená novou nejvyšší nabídku
self.highestBidder = msg.sender
self.highestBid = msg.value
# Vybere dříve vrácenou nabídku. Vzor výběru se
# zde používá k zamezení bezpečnostnímu problému. Pokud by se vrácení peněz posílalo přímo
# jako součást bid(), škodlivý přihazující kontrakt by mohl zablokovat
# tato vrácení peněz a tím zablokovat příchod nových vyšších nabídek.
@external
def withdraw():
pending_amount: uint256 = self.pendingReturns[msg.sender]
self.pendingReturns[msg.sender] = 0
send(msg.sender, pending_amount)
# Ukončí aukci a odešle nejvyšší nabídku
# příjemci.
@external
def endAuction():
# Je dobrým pravidlem strukturovat funkce, které interagují
# s jinými kontrakty (tj. volají funkce nebo posílají ether)
# do tří fází:
# 1. kontrola podmínek
# 2. provádění akcí (potenciálně měnící podmínky)
# 3. interakce s jinými kontrakty
# Pokud se tyto fáze smíchají, mohl by jiný kontrakt zavolat
# zpět do aktuálního kontraktu a upravit stav nebo způsobit,
# že se efekty (výplata etheru) provedou vícekrát.
# Pokud interně volané funkce zahrnují interakci s externími
# kontrakty, musí být také považovány za interakci s
# externími kontrakty.
# 1. Podmínky
# Zkontroluje, zda bylo dosaženo času konce aukce
assert block.timestamp >= self.auctionEnd
# Zkontroluje, zda již byla tato funkce zavolána
assert not self.ended
# 2. Efekty
self.ended = True
# 3. Interakce
send(self.beneficiary, self.highestBid)
Tento příklad by vám měl poskytnout představu o tom, jak vypadá syntaxe kontraktu ve Vyperu. Podrobnější popis funkcí a proměnných najdete v dokumentaci (opens in a new tab).
Yul a Yul+
Pokud jste v Ethereu nováčkem a ještě jste neprogramovali v žádném jazyce pro chytré kontrakty, doporučujeme začít se Solidity nebo Vyperem. Yul nebo Yul+ prozkoumejte až tehdy, když budete obeznámeni s osvědčenými postupy zabezpečení chytrých kontraktů a specifiky práce s EVM.
Yul
- Mezijazyk pro Ethereum.
- Podporuje EVM a Ewasm (opens in a new tab), což je WebAssembly přizpůsobené pro Ethereum, a je navržen tak, aby byl použitelným společným jmenovatelem obou platforem.
- Dobrý cíl pro vysokoúrovňové fáze optimalizace, ze kterých mohou těžit platformy EVM i Ewasm stejnou měrou.
Yul+
- Nízkoúrovňové, vysoce efektivní rozšíření jazyka Yul.
- Původně navrženo pro kontrakt typu optimistický rollup.
- Na Yul+ lze pohlížet jako na experimentální návrh upgradu jazyka Yul, který do něj přidává nové funkce.
Důležité odkazy
- Dokumentace k Yul (opens in a new tab)
- Dokumentace k Yul+ (opens in a new tab)
- Úvodní článek o Yul+ (opens in a new tab)
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.
{
function power(base, exponent) -> result
{
switch exponent
case 0 { result := 1 }
case 1 { result := base }
default
{
result := power(mul(base, base), div(exponent, 2))
if mod(exponent, 2) { result := mul(base, result) }
}
}
let res := power(calldataload(0), calldataload(32))
mstore(0, res)
return(0, 32)
}
Pokud již máte s chytrými kontrakty bohaté zkušenosti, plnou implementaci ERC-20 v jazyce Yul najdete zde (opens in a new tab).
Fe
- Staticky typovaný jazyk pro Ethereum Virtual Machine (EVM).
- Inspirováno jazyky Python a Rust.
- Klade si za cíl být snadno naučitelný – a to i pro vývojáře, kteří jsou v ekosystému Etherea nováčky.
- Vývoj jazyka Fe je stále v rané fázi, jazyk měl svou alfa verzi v lednu 2021.
Důležité odkazy
- GitHub (opens in a new tab)
- Oznámení o Fe (opens in a new tab)
- Plán vývoje Fe pro rok 2021 (opens in a new tab)
- Chat Fe na Discordu (opens in a new tab)
- Twitter Fe (opens in a new tab)
Příklad kontraktu
Následuje jednoduchý kontrakt implementovaný v jazyce Fe.
type BookMsg = bytes[100]
contract GuestBook:
pub guest_book: map<address, BookMsg>
event Signed:
book_msg: BookMsg
pub def sign(book_msg: BookMsg):
self.guest_book[msg.sender] = book_msg
emit Signed(book_msg=book_msg)
pub def get_msg(addr: address) -> BookMsg:
return self.guest_book[addr].to_mem()
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 danou práci a také o osobní preference.
Zde je několik věcí, které byste měli zvážit, pokud jste ještě žádný z těchto jazyků nevyzkoušeli:
Co je skvělé na Solidity?
- Pokud jste začátečník, existuje mnoho tutoriálů a výukových nástrojů. Více se o tom dozvíte v sekci Učte se programováním.
- K dispozici jsou dobré vývojářské nástroje.
- Solidity má velkou komunitu vývojářů, což znamená, že s největší pravděpodobností najdete odpovědi na své otázky poměrně rychle.
Co je skvělé na Vyperu?
- Skvělý způsob, jak začít pro vývojáře v Pythonu, kteří chtějí psát chytré kontrakty.
- Vyper má menší počet funkcí, což z něj dělá skvělý nástroj pro rychlé prototypování nápadů.
- Vyper si klade za cíl být snadno auditovatelný a maximálně čitelný pro lidi.
Co je skvělé na Yul a Yul+?
- Zjednodušený a funkční nízkoúrovňový jazyk.
- Umožňuje dostat se mnohem blíže k samotnému EVM, což může pomoci optimalizovat spotřebu gasu vašich kontraktů.
Srovnání jazyků
Pro srovnání základní syntaxe, životního cyklu kontraktu, rozhraní, operátorů, datových struktur, funkcí, řízení toku a dalších věcí se podívejte na tento tahák od Auditless (opens in a new tab)