Přejít na hlavní obsah
Change page

Anatomie chytrých kontraktů

Chytrý kontrakt je program, který běží na určité adrese na Ethereu. Skládá se z dat a funkcí, které se mohou spustit po přijetí transakce. Zde je přehled toho, z čeho se chytrý kontrakt skládá.

Předpoklady

Ujistěte se, že jste si nejprve přečetli o chytrých kontraktech. Tento dokument předpokládá, že již znáte programovací jazyky, jako je JavaScript nebo Python.

Data

Jakákoli data kontraktu musí být přiřazena k určitému umístění: buď do storage nebo do memory. Úprava úložiště (storage) v chytrém kontraktu je nákladná, takže musíte zvážit, kde by vaše data měla být uložena.

Úložiště (Storage)

Trvalá data se označují jako úložiště (storage) a jsou reprezentována stavovými proměnnými. Tyto hodnoty se trvale ukládají na blockchain. Musíte deklarovat jejich typ, aby kontrakt při kompilaci věděl, kolik úložného prostoru na blockchainu bude potřebovat.

// Příklad v Solidity
contract SimpleStorage {
    uint storedData; // Stavová proměnná
    // ...
}
# Příklad ve Vyper
storedData: int128

Pokud jste již programovali v objektově orientovaných jazycích, pravděpodobně budete většinu typů znát. Nicméně typ address pro vás bude pravděpodobně nový, pokud s vývojem pro Ethereum teprve začínáte.

Typ address může uchovávat adresu na Ethereu, což odpovídá 20 bajtům nebo 160 bitům. Vrací se v hexadecimálním zápisu s počátečním 0x.

Mezi další typy patří:

  • boolean (pravdivostní hodnota)
  • integer (celé číslo)
  • čísla s pevnou řádovou čárkou
  • pole bajtů pevné délky
  • pole bajtů dynamické délky
  • racionální a celočíselné literály
  • řetězcové literály
  • hexadecimální literály
  • výčtové typy (enums)

Pro podrobnější vysvětlení se podívejte do dokumentace:

Paměť (Memory)

Hodnoty, které jsou uloženy pouze po dobu provádění funkce kontraktu, se nazývají paměťové proměnné (memory variables). Vzhledem k tomu, že nejsou trvale uloženy na blockchainu, je jejich použití mnohem levnější.

Přečtěte si více o tom, jak Ethereum Virtual Machine (EVM) ukládá data (Storage, Memory a Stack) v dokumentaci Solidity (opens in a new tab).

Proměnné prostředí

Kromě proměnných, které definujete ve svém kontraktu, existují i některé speciální globální proměnné. Používají se především k poskytování informací o blockchainu nebo aktuální transakci.

Příklady:

VlastnostStavová proměnnáPopis
block.timestampuint256Časové razítko epochy aktuálního bloku
msg.senderaddressOdesílatel zprávy (aktuálního volání)

Funkce

Zjednodušeně řečeno, funkce mohou získávat nebo nastavovat informace v reakci na příchozí transakce.

Existují dva typy volání funkcí:

  • internal – nevytvářejí volání EVM
    • K interním funkcím a stavovým proměnným lze přistupovat pouze interně (tj. z aktuálního kontraktu nebo z kontraktů, které z něj dědí)
  • external – vytvářejí volání EVM
    • Externí funkce jsou součástí rozhraní kontraktu, což znamená, že je lze volat z jiných kontraktů a prostřednictvím transakcí. Externí funkci f nelze volat interně (tj. f() nefunguje, ale this.f() funguje).

Mohou být také public nebo private

  • Funkce public lze volat interně zevnitř kontraktu nebo externě prostřednictvím zpráv
  • Funkce private jsou viditelné pouze pro kontrakt, ve kterém jsou definovány, a nikoli v odvozených kontraktech

Funkce i stavové proměnné mohou být veřejné (public) nebo soukromé (private)

Zde je funkce pro aktualizaci stavové proměnné v kontraktu:

// Příklad v Solidity
function update_name(string value) public {
    dapp_name = value;
}
  • Parametr value typu string je předán do funkce: update_name
  • Je deklarována jako public, což znamená, že k ní má přístup kdokoli
  • Není deklarována jako view, takže může upravovat stav kontraktu

Funkce View

Tyto funkce slibují, že nebudou upravovat stav dat kontraktu. Běžnými příklady jsou funkce typu „getter“ – můžete je použít například k získání zůstatku uživatele.

// Příklad v Solidity
function balanceOf(address _owner) public view returns (uint256 _balance) {
    return ownerPizzaCount[_owner];
}
dappName: public(string)

@view
@public
def readName() -> string:
  return dappName

Co se považuje za úpravu stavu:

  1. Zápis do stavových proměnných.
  2. Emitování událostí (opens in a new tab).
  3. Vytváření dalších kontraktů (opens in a new tab).
  4. Použití selfdestruct.
  5. Odesílání etheru prostřednictvím volání.
  6. Volání jakékoli funkce, která není označena jako view nebo pure.
  7. Použití nízkoúrovňových volání (low-level calls).
  8. Použití inline assembleru, který obsahuje určité operační kódy (opcodes).

Konstruktory

Funkce constructor se spustí pouze jednou, když je kontrakt poprvé nasazen. Stejně jako constructor v mnoha třídně orientovaných programovacích jazycích, tyto funkce často inicializují stavové proměnné na jejich zadané hodnoty.

# Příklad ve Vyper

@external
def __init__(_beneficiary: address, _bidding_time: uint256):
    self.beneficiary = _beneficiary
    self.auctionStart = block.timestamp
    self.auctionEnd = self.auctionStart + _bidding_time

Vestavěné funkce

Kromě proměnných a funkcí, které definujete ve svém kontraktu, existují i některé speciální vestavěné funkce. Nejzřejmějším příkladem je:

  • address.send() – Solidity
  • send(address) – Vyper

Ty umožňují kontraktům odesílat ETH na jiné účty.

Psaní funkcí

Vaše funkce potřebuje:

  • proměnnou parametru a typ (pokud přijímá parametry)
  • deklaraci internal/external
  • deklaraci pure/view/payable
  • návratový typ (pokud vrací hodnotu)

Kompletní kontrakt by mohl vypadat nějak takto. Zde funkce constructor poskytuje počáteční hodnotu pro proměnnou dapp_name.

Události a logy

Události umožňují vašemu chytrému kontraktu komunikovat s vaším frontendem nebo jinými odebírajícími aplikacemi. Jakmile je transakce ověřena a přidána do bloku, chytré kontrakty mohou emitovat události a logovat informace, které pak frontend může zpracovat a využít.

Komentované příklady

Zde jsou některé příklady napsané v jazyce Solidity. Pokud si chcete s kódem pohrát, můžete s ním interagovat v prostředí Remix (opens in a new tab).

Hello world

Token

Unikátní digitální aktivum

Další čtení

Pro ucelenější přehled o chytrých kontraktech se podívejte do dokumentace jazyků Solidity a Vyper: