Blockchain umí vést účetní knihu bez správce. Smart kontrakt je krok dál: program uložený v té knize, který se spustí, když ho někdo zavolá, a jehož výsledek ověří celá síť.
Název je nešťastný. Není to smlouva a není v tom nic chytrého. Je to kód, který běží předvídatelně a nikdo ho nemůže zastavit, což je zároveň jeho síla i jeho hlavní nebezpečí.
Co je na tom nezvyklé
Program v blockchainu se od běžného kódu liší v několika věcech, které mění způsob, jak se píše:
| Vlastnost | Důsledek |
|---|---|
| Je veřejný | kdokoli si přečte tvůj kód i data, včetně útočníka |
| Je neměnný | chybu nejde opravit nasazením opravy |
| Spouští ho kdokoli | nepředpokládej, že volání přijde z tvého rozhraní |
| Každý krok stojí peníze | cyklus přes velké pole může být neproveditelný |
| Nemá přístup ven | nezná čas přesně, nevidí internet, neumí náhodu |
| Je deterministický | musí všem uzlům vyjít stejně, jinak by se síť neshodla |
Ta poslední vlastnost je zásadní a plyne z ní víc, než se zdá. Kontrakt nemůže sáhnout na internet, protože každý uzel by dostal jinou odpověď a shoda by se rozpadla. Nemůže ani použít skutečnou náhodu ze stejného důvodu.
Kde se dělá největší chyba v uvažování
Kontrakt neběží sám od sebe. Nemá vlastní vlákno, nemá časovač a nemůže se spustit v pondělí v osm. Existuje jen jako reakce na transakci, kterou někdo poslal a zaplatil.
Když chceš, aby se něco stalo pravidelně, musí to někdo zvenčí odpálit a zaplatit za to. Proto existují služby, které tohle dělají, a proto se v návrzích objevuje pobídka pro toho, kdo funkci zavolá.
Neměnnost je past i vlastnost
Nasazený kontrakt už nezměníš. To je celý smysl: uživatel má jistotu, že pravidla se pod ním nezmění. Zároveň to znamená, že chyba je trvalá.
V praxi se to obchází proxy vzorem: uživatelé volají adresu, která jen přeposílá volání na skutečnou implementaci, a tu jde vyměnit. Získáš tím možnost opravovat, ale zaplatíš tím, že někdo tu výměnu může provést, tedy se vrací důvěryhodná strana.
To je poctivé shrnutí celé oblasti: buď je to neměnné a musí to být bezchybné, nebo je to opravitelné a musíš věřit tomu, kdo opravuje. Třetí možnost neexistuje.
Na co se to hodí a na co ne
Hodí se tam, kde je potřeba, aby se pravidlo vykonalo bez ohledu na vůli kterékoli strany: úschova prostředků, směna bez prostředníka, rozdělování podle předem daného klíče, hlasování s ověřitelným výsledkem.
Nehodí se tam, kde je potřeba úsudek, kde se pravidla mění, kde je nutná náprava omylu, nebo kde by data byla citlivá. Všechno v kontraktu je veřejné a navždy.
Cvičení
- Chceš kontrakt, který každý měsíc rozdělí vybrané prostředky. Proč to nejde napsat přímo a jak se to řeší?
- Proč nemůže kontrakt zavolat API na kurz měny?
- Kdy je proxy vzor správná volba a co tím ztrácíš?
Náčrt řešení: rozbal, až si cvičení zkusíš sám
- Protože kontrakt nemá vlastní běh a nespustí se sám. Existuje jen jako reakce na transakci, kterou musí někdo poslat a zaplatit za ni. Řeší se to tak, že kontrakt má funkci „rozděl, pokud už uplynul měsíc", kterou může zavolat kdokoli, a bývá v ní odměna pro toho, kdo ji zavolá, aby se to někomu vyplatilo. Alternativou je externí služba, která volání plánuje, což ale přidává stranu, na které závisíš.
- Protože by každý uzel dostal jinou odpověď a síť by se neshodla na výsledku. Kontrakt musí být deterministický: při stejném vstupu a stejném stavu musí všem vyjít totéž, jinak nejde ověřit, že provedení bylo správné. Data zvenčí se proto dostávají dovnitř jinak, totiž tak, že je někdo zapíše transakcí. Tomu se říká oracle a má to vlastní rizika, viz oracles.
- Když počítáš s tím, že budeš muset opravovat, a jsi ochoten za to zaplatit důvěrou. Ztrácíš neměnnost, tedy tu vlastnost, kvůli které se to celé staví: někdo má klíč, kterým může logiku vyměnit, a uživatel mu musí věřit, že to neudělá ve svůj prospěch. Zmírňuje se to tím, že výměnu ovládá multisig nebo že je zpožděná časovým zámkem, aby uživatelé stihli odejít. Úplně to ale nezmizí.
Shrnutí
- Smart kontrakt je veřejný, neměnný a deterministický program uložený v blockchainu.
- Neběží sám; spouští se jen transakcí, kterou někdo pošle a zaplatí.
- Nemá přístup k internetu ani ke skutečné náhodě, protože by se uzly neshodly.
- Neměnnost znamená, že chybu nejde opravit; proxy vzor to řeší za cenu návratu důvěry.
- Hodí se tam, kde má pravidlo platit bez ohledu na vůli stran, ne tam, kde je potřeba úsudek.
Proč nemůže smart kontrakt volat externí API?
Protože musí být deterministický. Každý uzel provádí tentýž kód a musí mu vyjít stejný výsledek, jinak se síť neshodne na stavu. Externí služba by odpověděla různě podle času nebo dostupnosti, takže data zvenčí musí dovnitř dostat někdo transakcí, čemuž se říká oracle.
Proč se kontrakt nespustí sám v daný čas?
Nemá vlastní běh ani plánovač; existuje jen jako reakce na příchozí transakci, za kterou někdo zaplatil. Pravidelné akce se proto řeší funkcí, kterou smí zavolat kdokoli, obvykle s odměnou pro volajícího, nebo externí službou, která volání plánuje.
Jaký je kompromis mezi neměnným a aktualizovatelným kontraktem?
Neměnný kontrakt dává uživateli jistotu, že se pravidla nezmění, ale chyba v něm je trvalá. Aktualizovatelný přes proxy jde opravit, ale někdo má pravomoc logiku vyměnit, takže se vrací důvěryhodná strana. Zmírňuje se to multisigem a časovým zámkem, ale odstranit to nejde.
