Jazyk chytrých smluv
Poslední úpravy: @headwitch(opens in a new tab), 17. června 2024
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 jiným jazykem používajícím složené závorky(opens in a new tab), můžete si najít jazyk s podobnou 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 webový Remix IDE(opens in a new tab), abyste mohli začít kódovat.
Zkušenější vývojáři mohou také chtít používat Yul, což je intermediární jazyk pro Virtuální stroj Etherea, 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 smart 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.
Důležité odkazy
- Dokumentace(opens in a new tab)
- Portál jazyka Solidity(opens in a new tab)
- Solidity by Example(opens in a new tab)
- GitHub(opens in a new tab)
- Solidity Gitter Chatroom(opens in a new tab) propojeno se Solidity Matrix Chatroom(opens in a new tab)
- Tahák(opens in a new tab)
- Blog Solidity(opens in a new tab)
- Twitter Solidity(opens in a new tab)
Ukázkový kontrakt
1// SPDX-License-Identifier: GPL-3.02pragma solidity >= 0.7.0;34contract Coin {5 // The keyword "public" makes variables6 // accessible from other contracts7 address public minter;8 mapping (address => uint) public balances;910 // Events allow clients to react to specific11 // contract changes you declare12 event Sent(address from, address to, uint amount);1314 // Constructor code is only run when the contract15 // is created16 constructor() {17 minter = msg.sender;18 }1920 // Sends an amount of newly created coins to an address21 // Can only be called by the contract creator22 function mint(address receiver, uint amount) public {23 require(msg.sender == minter);24 require(amount < 1e60);25 balances[receiver] += amount;26 }2728 // Sends an amount of existing coins29 // from any caller to an address30 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šeKopírovat
Tento příklad by vám měl poskytnout představu o tom, jaká je syntaxe kontraktů v Solidity. Pro podrobnější popis funkcí a proměnných si přečtěte dokumentaci(opens 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 rationale(opens in a new tab).
Důležité odkazy
- Dokumentace(opens in a new tab)
- Vyper by Example(opens in a new tab)
- More Vyper by Example(opens in a new tab)
- GitHub(opens in a new tab)
- Discord chat Vyper komunity(opens in a new tab)
- Tahák(opens in a new tab)
- Frameworky a nástroje pro vývoj smart kontraktů v jazyce Vyper
- VyperPunk – naučte se zabezpečit a hackovat smart kontrakty v jazyce Vyper(opens in a new tab)
- VyperExamples – příklady zranitelnosti ve Vyper(opens in a new tab)
- Vyper Hub pro vývojáře(opens in a new tab)
- Příklady nejlepších chytrých kontraktů na Vyper(opens in a new tab)
- Úžasné Vyperem kurátorované zdroje(opens in a new tab)
Příklad
1# Open Auction23# Auction params4# Beneficiary receives money from the highest bidder5beneficiary: public(address)6auctionStart: public(uint256)7auctionEnd: public(uint256)89# Current state of auction10highestBidder: public(address)11highestBid: public(uint256)1213# Set to true at the end, disallows any change14ended: public(bool)1516# Keep track of refunded bids so we can follow the withdraw pattern17pendingReturns: public(HashMap[address, uint256])1819# Create a simple auction with `_bidding_time`20# seconds bidding time on behalf of the21# beneficiary address `_beneficiary`.22@external23def __init__(_beneficiary: address, _bidding_time: uint256):24 self.beneficiary = _beneficiary25 self.auctionStart = block.timestamp26 self.auctionEnd = self.auctionStart + _bidding_time2728# Bid on the auction with the value sent29# together with this transaction.30# The value will only be refunded if the31# auction is not won.32@external33@payable34def bid():35 # Check if bidding period is over.36 assert block.timestamp < self.auctionEnd37 # Check if bid is high enough38 assert msg.value > self.highestBid39 # Track the refund for the previous high bidder40 self.pendingReturns[self.highestBidder] += self.highestBid41 # Track new high bid42 self.highestBidder = msg.sender43 self.highestBid = msg.value4445# Withdraw a previously refunded bid. The withdraw pattern is46# used here to avoid a security issue. If refunds were directly47# sent as part of bid(), a malicious bidding contract could block48# those refunds and thus block new higher bids from coming in.49@external50def withdraw():51 pending_amount: uint256 = self.pendingReturns[msg.sender]52 self.pendingReturns[msg.sender] = 053 send(msg.sender, pending_amount)5455# End the auction and send the highest bid56# to the beneficiary.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. checking conditions63 # 2. performing actions (potentially changing conditions)64 # 3. interacting with other contracts65 # If these phases are mixed up, the other contract could call66 # back into the current contract and modify the state or cause67 # effects (ether payout) to be performed multiple times.68 # If functions called internally include interaction with external69 # contracts, they also have to be considered interaction with70 # external contracts.7172 # 1. Conditions73 # Check if auction endtime has been reached74 assert block.timestamp >= self.auctionEnd75 # Check if this function has already been called76 assert not self.ended7778 # 2. Effects79 self.ended = True8081 # 3. Interaction82 send(self.beneficiary, self.highestBid)Zobrazit všeKopírovat
Tento příklad by vám měl poskytnout představu o tom, jaká je syntaxe kontraktů ve Vyperu. Pro podrobnější popis funkcí a proměnných si přečtěte dokumentaci(opens 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 i Ewasm(opens in a new tab), což je varianta WebAssembly přizpůsobená pro Ethereum, a je navržen tak, aby byl použitelným společným základem pro obě platformy.
- 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žen 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.
Důležité odkazy
- Dokumentace Yul(opens in a new tab)
- Dokumentace Yul+(opens in a new tab)
- Playground Yul+(opens in a new tab)
- Úvodní příspěvek Yul+(opens in a new tab)
Ukázkový kontrakt
Následující jednoduchý příklad implementuje funkci mocniny. Lze jej zkompilovat pomocí příkazu 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) -> 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}Zobrazit vše
Pokud již máte se smart kontrakty bohaté zkušenosti, plnou implementaci ERC20 v Yul můžete najít zde(opens 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.
Důležité odkazy
- GitHub(opens in a new tab)
- Oznámení Fe(opens in a new tab)
- Plán vylepšení Fe pro rok 2021(opens in a new tab)
- Chat na Discordu Fe(opens in a new tab)
- Twitter Fe(opens in a new tab)
Ukázkový kontrakt
Následuje jednoduchý kontrakt implementovaný v jazyce 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()16Zobrazit 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 dozvíte v sekci Learn by Coding.
- 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ů.
Porovnání jazyků
Pro srovnání základní syntaxe, životního cyklu kontraktů, rozhraní, operátorů, datových struktur, funkcí, řídicích struktur a dalších rozdílů se podívejte na tento cheatsheet od Auditless(opens in a new tab)