🇨🇿 Pochopení Extended-UTXO modelu Cardana

Jednou z inovací, se kterou Cardano přišlo, je rozšíření účetního modelu Bitcoinu. Bitcoin je v podstatě jednoduchý, ale to neznamená, že jeho jednotlivé části nelze vylepšit. V rámci projektu Cardano dochází k technologickému pokroku. Pojďte se seznámit s historií účetních modelů a jejich vývojem.

Satoshi Nakamoto použil k vytvoření Bitcoinu mnoho technologií. Jednou z nich byl účetní model využívající výstup z nespotřebovaných transakcí (UTxO). Vitalik Buterin a jeho tým se rozhodli použít jiný účetní model založený na účtech, protože se zdál být lepším řešením pro provádění inteligentních kontraktů. V článku jej budeme nazývat model založený na účtech.

V současné době používá stejný účetní model jako Ethereum mnoho projektů, například Solana, Polkadot a Algorand. Oba přístupy mají své výhody i nevýhody a vývojáři se při budování nad základními vrstvami potýkají s různými problémy. Tým IOG budující Cardano se rozhodl jít jinou cestou a rozšířil původní model Bitcoinu, UTXO. Nový model byl pojmenován Extended-UTXO.

Účetní model

Účetnictví je základem dnešního finančního světa. Každý finanční subjekt potřebuje sledovat zůstatky na jednotlivých účtech a peněžní toky. Účetní kniha je také základem blockchainových sítí, protože ve svém jádru představuje globální rozvahu, která nám dává odpověď na otázku, kdo a v jakém čase vlastní jaká aktiva.

Blockchain zaznamenává celou historii transakcí. Záznamy v blockchainu lze velmi snadno kontrolovat. Blockchain přichází s jednou velkou výhodou. Umožňuje nám vlastnit aktiva bez zbytečných prostředníků a zajišťuje, že nikdo v systému nemůže podvádět.

Blockchain síť má v zásadě dva základní úkoly. Udržovat účetní knihu a umožnit převod hodnoty z účtu na účet prostřednictvím transakcí. První generace blockchainových sítí umožňovala pouze bezpodmínečné posílání transakcí (převod z účtu Alice na účet Boba). Druhá generace přidala programovatelnost, tj. možnost posílat transakce podmíněně. Pro vývojáře třetích stran jsou k dispozici nástroje, které jim umožňují psát a nasazovat programy (chytré kontrakty/skripty), které může síť decentralizovaně vykonávat. Na první generaci blockchainové sítě lze pohlížet jako na PayPal. Druhá generace umožní vytvořit komplexní bankovní systém.

V tradičním světě financí se lidé spoléhají na účetní a sofistikované centralizované systémy. Aby účetní nepodváděli, je nutné monitorovat finanční toky, aktivně zavádět opatření proti podvodům a kontrolovat účetní knihy.

Blockchainové sítě se spoléhají na pravidla, která jsou zapsána ve zdrojovém kódu. Za předpokladu, že je zdrojový kód správně implementován a chová se tak, jak většina lidí očekává, není třeba žádných bezpečnostních opatření a všechna data jsou dostupná všem. Každý může mít na svém počítači globální účetní knihu a přímo komunikovat se sítí. To umožňuje Peer-to-Peer interakci mezi uživateli, kde je decentralizovaná síť důvěryhodným prostředníkem.

Jak chápat blockchain z pohledu bloků

Blockchain je v podstatě specifická databáze, která dokáže zajistit neměnnost historických záznamů. Tyto záznamy se týkají převodů hodnot mezi uživateli, které probíhají prostřednictvím transakcí. Blockchain vždy zná přesnou odpověď na otázku, který uživatel X vlastnil token Y v čase Z. Protože je blockchain pseudoanonymní, místo konkrétních uživatelů se používají adresy blockchainu. Blockchain uchovává historii všech provedených transakcí od samého počátku až do současnosti. Kromě toho zajišťuje, že historii nelze přepsat.

Technicky je blockchain stavový stroj, protože si pamatuje předchozí události, které se nazývají stavy systému. Tyto události představují interakce mezi uživateli. Stav lze měnit za předem definovaných podmínek. Každý protokol má implementovanou logiku, která umožňuje přechod stavu z S-0 do S+1. V pravidelných intervalech síť vytváří nové bloky, v jejichž rámci dochází k tzv. přechodu stavu.

Rozdíl mezi modelem UTXO a modelem založeným na účetnictví spočívá ve způsobu zpracování účetnictví. S přechodem stavu z hlediska přidávání nových bloků nemá nic společného. Nový blok je vytvořen jedním uzlem a musí být vysílán do sítě. Každý nový blok obsahuje sadu transakcí, a pokud je přijat většinou účastníků sítě (technicky vzato plnými uzly, které se aktivně podílejí na konsensu sítě), dojde k přechodu stavu. Pokud je blok přijat, jsou přijaty i všechny obsažené transakce. Nový blok se trvale uloží do blockchainu a s jeho přidáním se změní vlastníci aktiv přesně podle toho, jak to diktují přijaté transakce.

Úkolem blockchain sítě je v podstatě ověřovat transakce, vkládat platné transakce do nových bloků, ověřovat bloky a přidávat je do historie blockchainu. Dodejme, že tento proces probíhá decentralizovaně, takže nové transakce a bloky je třeba vysílat do celé sítě, která se stará o validaci.

Blockchainové adresy

Vlastnictví aktiv (mincí a tokenů) je reprezentováno vlastnictvím soukromého kryptografického klíče k dané adrese, která je odvozená od veřejného kryptografického klíče. Obvykle se adresa hashuje. Transakci si můžete představit jako konkrétní zprávu do sítě, v níž odesílatel dává pokyn k převodu vybraného počtu aktiv z adresy odesílatele na adresu příjemce. Platná transakce musí obsahovat důkaz, že odesílatel je skutečným vlastníkem tokenů. K tomu se používá soukromý kryptografický klíč, kterým se transakce podepisuje. Síť, respektive každý uzel, je schopen podpis ověřit a vyhodnotit, zda je transakce platná. U jednoduchých transakcí je ověřování založeno pouze na dvojici soukromého a veřejného klíče.

OBRÁZEK: Peněženka pomůže uživatelům generovat blockchainové adresy a posílat podepsané transakce. Síť transakci ověří prostřednictvím veřejného klíče, a pokud je platná, bude zařazena do nového bloku.

Pokud je transakce přijata a je obsažena v bloku, který byl přidán do blockchainu, majetek bude vlastnit majitel adresy příjemce. Pouze nový vlastník je může utratit, opět prostřednictvím podpisu provedeného soukromým klíčem. Uživatel si samozřejmě může aktiva posílat sám sobě.

Tento koncept je stejný jak pro model UTXO, tak pro model založený na účtech, protože je založen na kryptografii veřejného klíče (asymetrická kryptografie).

Je důležité si uvědomit, že to, co uživatelé vnímají jako mince nebo tokeny, jsou ve skutečnosti jen digitální čísla spojená s adresami blockchainu. Účelem transakce je přenést číslo z adresy odesílatele a přiřadit stejnou hodnotu jedné adrese nebo ji rozdělit mezi více adres příjemce. Protože jsou vyžadovány poplatky, hodnota se obvykle rozdělí mezi více adres. Hodnota na vstupu a výstupu transakce musí být vždy stejná. Během společné transakce nelze hodnotu vytvořit ani ztratit. Sítě obvykle definují pravidla pro vytvoření nové hodnoty.

Kdykoli se mluví o mincích nebo tokenech, včetně tohoto článku, mluví se ve skutečnosti o číslech. Tokeny jsou jen abstrakcí čísel, která je pro uživatele snadno pochopitelná.

Uživatelé se svými aktivy zacházejí jako se zůstatkem na svých účtech. Peněženky generují všechny páry soukromých a privátních klíčů, takže znají všechny veřejné adresy uživatelů. Všechny vytvořené adresy mohou obsahovat aktiva. Peněženka sečte všechny tokeny na adresách (sečte všechna digitální čísla) a zobrazí je uživateli jako zůstatek. Peněženka by mohla mít pouze jednu jedinou adresu a vše by fungovalo úplně stejně.

Rozdíl mezi modelem UTXO a modelem založeným na účtech

Rozdíl mezi modelem UTXO a modelem založeným na účtech spočívá v tom, jak jsou aktiva na adresách uložena a jak je s nimi nakládáno při transakcích. Jinými slovy, jak tyto dva různé modely nakládají se zůstatky a jak je zaznamenáván stav systému. V širším kontextu je důležité, jaká pravidla a podmínky jsou definovány (a implementovány ve zdrojovém kódu uzlů) při vytváření nového bloku. Nedílnou součástí přenosu hodnot je validace sítí.

Nespotřebovaný transakční výstup (UTXO) je technický termín pro počet digitálních aktiv, která zůstávají po zpracované transakci. UTXO je digitální číslo, které si můžete představit jako počet aktiv. V modelu UTXO můžete termíny UTXO a aktivum (mince nebo token) používat zaměnitelně.

Cardano používá rozšířený model UTXO, který se nazývá Extended-UTXO (EUTXO). V modelu EUTXO se převod aktiv zaznamenává jako směrovaný acyklický graf (DAG) mezi adresami. Ačkoli to zní děsivě, není třeba se toho bát. Ve skutečnosti je to snadno pochopitelné.

Jak jsme si řekli, každé UTXO je reprezentováno digitálním číslem a je abstrakcí mince nebo tokenu. UTXO si můžete představit jako fyzické bankovky nebo mince, ale s tím rozdílem, že nejsou definovány nominální hodnoty, které UTXO musí mít. Například 10 mincí ADA může být jedno UTXO. Také 12 mincí ADA může být UTXO. Dokonce i 116,85 může být jedno UTXO.

Nyní si představte, že Alice má v peněžence všechny tři UTXO. Nezáleží na tom, zda má všechny tři UTXO na stejné adrese, nebo zda je každé UTXO na své vlastní adrese. Pokud chce Alice znát svůj zůstatek, musí sečíst všechny UTXO. Její peněženka to udělá za Alici. Její zůstatek je 10 + 12 + 116,85 = 138,85 ADA.

OBRÁZEK: Stejný zůstatek v peněžence může být při rozdělování UTXO na adresy reprezentován různě. Můžete mít 3 UTXO na jedné adrese nebo 3 UTXO na 3 adresách.

Podívejme se, co se stane, když se Alice rozhodne poslat Bobovi 15 UTXO. Bob má ve své peněžence 21 ADA na jedné adrese. Rozhodne se vytvořit novou adresu, na kterou od Alice obdrží 15 ADA. Aličina peněženka musí použít 2 UTXO. Peněženka si vybere UTXO s 10 a 12 ADA. UTXO s 10 ADA je vyčerpáno v plné výši. Z UTXO s 12 ADA se vybere pouze 5 ADA + 0,2 ADA (transakční poplatek).

Po přijetí transakce bude mít Alice pouze 2 UTXO s 6,8 a 116,85 ADA. Celkem bude mít Alice 123,65 ADA. Bob bude mít 2 UTXO s 21 a 15 UTXO. Celkem bude mít Bob 36 ADA. Na adresu poplatku bude přidáno 0,2 ADA.

OBRÁZEK: Prostřednictvím transakce byl proveden přechod mezi dvěma stavy. Transakce byla vytvořena ve stavu N (blok N) a byla zařazena do bloku N+1.

Přechod mezi dvěma stavy (bloky) byl proveden prostřednictvím transakce. Důležité je složení transakce. Transakce má vstupy a výstupy. Všimněte si, jak se hodnoty na vstupu mění na hodnoty na výstupu podle potřeb transakce, přesně tak, jak ji odesílatel (peněženka) sestavil. Každý UTXO v transakci musí být utracen jako celek, protože záznamy v předchozích blocích nelze upravovat. Vstupem je soubor UTXO, které mají být utraceny, tj. celková hodnota bude transakcí použita k vytvoření výstupů. Výstupem transakce je rovněž sada UTXO, které budou přiřazeny nové adrese. Alternativně mohou být některé nebo všechny UTXO přiřazeny stejné adrese s různými hodnotami. Uživatel může mít na jedné adrese 3 UTXO a přeje si mít na stejné adrese pouze 1 UTXO. Celková hodnota zůstává stejná.

V našem příkladu jsme měli dva vstupy a tři výstupy. Na vstupu byly 3 UTXO patřící Alici. Výstupem byly 3 UTXO. Konkrétně UTXO s 15 ADA pro Boba, UTXO s 0,2 ADA jako transakční poplatek a UTXO s 6,8 ADA, což je částka vrácená Alici. Aby byla transakce platná, musí se počet mincí na vstupu shodovat s počtem mincí na výstupu. V našem příkladu je to 22 mincí ADA.

Lidem může připadat zvláštní, že je nutné vrátit Alici 6,8 ADA. Je to podobné tomu, co vám vrátí pokladní v obchodě, pokud zaplatíte vyšší bankovkou, než je celková cena nákupu. Opět platí, že každé UTXO musí být utraceno v plné výši, takže je nutné zajistit, aby byl zbytek (pokud nějaký zbývá) vrácen Alici jako součást transakce.

Všimněte si, že model UTXO pracuje s jednotlivými UTXO při vytváření transakcí. Při utrácení určitého počtu tokenů je třeba vybrat potřebný počet vhodných UTXO. Pokud je součet tokenů ve vybraných UTXO větší než počet tokenů, které mají být utraceny, musí být zbytek vrácen jako nové UTXO na adresu odesílatele.

S UTXO se zachází stejně jako se skutečnými penězi. Pokud máte v obchodě zaplatit 85 dolarů, můžete zaplatit 100dolarovou bankovkou a pokladní vám vrátí 15 dolarů (10dolarové a 5dolarové bankovky). Nemůžete nějak odstřihnout 85 dolarů od 100dolarové bankovky a zaplatit jí. V peněžence můžete najít 17 pětidolarových bankovek a zaplatit jimi. Stejně tak můžete mít v peněžence Cardano 17 UTXO s 5 ADA.

Každé UTXO lze utratit pouze jednou a v budoucnu už nikdy. Po jeho utracení se vytvoří jedno nebo více nových UTXO, které lze následně utratit. Tento cyklus se neustále opakuje. Model UTXO je způsob organizace blockchainu tak, aby žádná aktiva nebyla utracena dvakrát. Blockchain přechází do nového stavu v pravidelných intervalech. Uživatelé mohou neutracené UTXO utratit v jakémkoli budoucím stavu. Například Bob může obdržet UTXO ve stavu N a rozhodnout se je utratit za 14 dní, což může být blok N+60 480. Utratit UTXO v podstatě znamená přenést hodnotu na jinou adresu.

V každém bloku probíhá několik transakcí, takže se utratí mnoho UTXO. Všechny transakce dohromady tvoří kolekci (blok), která představuje přechod mezi stavy. V modelu UTXO představuje celý graf výstupů transakcí, utracených i neutracených, globální stav. Je možné rozlišovat mezi aktuálním stavem a všemi předchozími stavy, což je v podstatě celá historie transakcí od prvního Genesis bloku.

Pokud by vás zajímal počet všech tokenů, které lze v aktuálním stavu utratit, museli byste spočítat všechny neutracené výstupy (UTXO). Jejich nalezení v podstatě znamená projít všechny transakce od bloku Genesis až po současnost. Plné uzly ověřují všechny transakce během synchronizace se sítí, takže znají aktuální sadu UTXOs.

Obrázek: Pozice UTXOs mezi stavy. Existuje 6 UTXO označené modrou barvou, které jsou nespotřebované.

Podívejme se nyní na model založený na účtu. Ten je podobný bankovnímu účtu. Stejně jako u modelu UTXO jsou aktiva digitálními čísly, která jsou spojena s blockchainovými adresami. V modelu založeném na účtu je u daného typu aktiva na adrese udržován pouze aktuální zůstatek. Transakce upravuje zůstatek na adresách tak, že odečte hodnotu z jedné adresy a přidá ji na jinou adresu.

Ilustrujme si to na příkladu. Alice má 138,85 ETH a rozhodne se poslat Bobovi 15 ETH. Bob má na svém zůstatku 21 ETH.

OBRÁZEK: Transakce mění zůstatky na obou adresách během přechodu stavu.

Transakce odečte 15 ETH od Alicina zůstatku a přidá je k Bobovu zůstatku. Dále se z Aličina zůstatku odečte transakční poplatek ve výši 0,15 ETH (GAS).

V modelu založeném na účtech lze globální stav chápat jako databázi všech účtů a jejich aktuálních zůstatků různých aktiv v síti. S každým přidáním nového bloku se stav systému aktualizuje podle všech transakcí, které jsou v bloku obsaženy. Počet účtů zůstává konstantní a nezávislý na počtu provedených transakcí, pokud zůstává konstantní počet uživatelů.

OBRÁZEK: Poslední stav N+3 je aktuální globální stav.

Všimněte si rozdílů mezi těmito dvěma modely. Model UTXO na úrovni protokolu nepracuje s myšlenkou peněženky nebo balancemi. Model je založen pouze na historii transakcí. Zůstatek uživatele musí být určen lokálně na základě historie převodů UTXO.

Zpět na bloky

Vraťme se nyní k blokům a vysvětleme jejich význam při přechodu mezi stavy. Každá transakce je v podstatě požadavek na změnu globálního stavu. V případě blockchainové sítě by s ní měla souhlasit potřebná většina uzlů v síti a přijmout nový stav. Synchronizace celé sítě s každou jednotlivou transakcí by byla velmi neefektivní z hlediska zdrojů. Globální synchronizace uzlů je časově náročný proces, protože informace musí být vysílána do celého světa. S rostoucím počtem transakcí by síť nebyla schopna synchronizace včas. Řešením je blok, který obsahuje více transakcí. V rámci synchronizace prostřednictvím bloků se zpracovává více uživatelských požadavků.

Bloky jsou srdcem blockchainových sítí. Bitcoin přechází z aktuálního stavu do nového stavu v průměru každých 10 minut. Cardano přibližně každých 20 sekund.

Protože každá jednotlivá transakce je žádostí o změnu stavu, blok se všemi transakcemi, které obsahuje, se stává žádostí o změnu stavu a je prostředkem synchronizace sítě. Má-li se změnit globální stav, musí požadovaná většina uzlů v síti celý blok přijmout. To znamená, že všechny transakce v bloku musí být platné jednotlivě i vzájemně. Například při ověřování nového bloku musí každý uzel zajistit, aby stejné aktivum nebylo utraceno dvakrát. Pokud celý blok neodpovídá pravidlům validace, bude sítí odmítnut.

OBRÁZEK: Síť blockchain se neustále synchronizuje. Přechod mezi stavy probíhá prostřednictvím bloků.

Blockchain je v podstatě posloupnost bloků, které jsou vzájemně propojeny takovým způsobem, že jejich pořadí nelze změnit. Ve většině současných sítí náhodně vybraný uzel vytvoří nový blok. Tento blok je pak vysílán všem ostatním uzlům v síti. Je důležité, aby se nový blok rozšířil po celé síti dříve, než jiný náhodně vybraný uzel vytvoří další nový blok, aby bylo možné nový blok propojit s předchozím blokem. Pokud by šíření nových bloků bylo příliš pomalé, vznikaly by vidlice (forky), což je nežádoucí stav. Při přidávání dalšího bloku k předchozímu by bylo nutné vybrat jeden ze dvou bloků, což znamená, že jeden z bloků by zůstal v blockchainu navždy a druhý by osiřel (se všemi transakcemi).

Modely UTXO a modely založené na účtech se neliší v konceptu přechodu do nového stavu na základě bloků. Zásadní rozdíl je v globální aktualizaci stavu. V modelu UTXO se globální stav rozšiřuje pouze vytvářením nových UTXO, zatímco v modelu založeném na účtech se globální stav aktualizuje na úrovni změn zůstatků.

Oba modely se také liší v tom, jak zpracovávají transakce. Model UTXO je ověřovací model. Transakce určují požadovaný výsledek přechodu stavu. Výsledek je definován jako nové UTXO, které je vytvořeno na základě vstupů transakce. Uzel ověřuje, zda jsou vstupy nevyčerpané a zda je platný digitální podpis transakce nebo jiné podmínky utracení. Model založený na účtu je výpočetní model. Transakce dávají návod, jak má vypadat přechod stavu. Uzly na základě instrukcí vypočítají nový stav. V obou případech může změna stavu vyžadovat provedení inteligentního kontraktu. Chytré kontrakty lze považovat za rozšíření instrukcí pro přechod stavu.

Rozdíly v modelech založených na UTXO a účtech mají důsledky, pokud jde o ověřování bloků, provádění chytrých smluv a škálovatelnost.

Pochopení základů

Než se pustíme do rozšířeného UTXO, je třeba stručně vysvětlit některé základní pojmy, které jsou vývojářům dobře známé, ale široké veřejnosti ne.

Začněme pojmy souběžnost a paralelismus.

Souběžnost znamená, že více výpočtů probíhá “téměř” současně. Uživatel může vnímat, že úlohy probíhají souběžně, ale na pozadí je pouze jeden aktér, který mezi úlohami velmi rychle přepíná. K tomu dochází, pokud máte počítač s jedním procesorem. Souběžnost umožňuje, aby textový editor a přehrávač hudby běžely současně. Proces věnuje každému z nich krátký čas, takže z pohledu uživatele se zdá, že běží současně. Je to proto, že procesor je mnohem rychlejší než lidské vnímání. Pokud má počítač více procesorů, může jednotlivé úlohy delegovat na vyhrazený procesor. Úlohy tak mohou běžet paralelně.

Aby bylo možné dosáhnout souběhu v rámci jedné velké úlohy nebo skupiny úloh (které spolu mohou, ale nemusí souviset), musí být možné rozdělit práci na menší části tak, aby bylo možné pracovat nezávisle na dílčích úlohách.

Má-li jeden aktér zpracovávat svazek úloh, může dokončit jednu úlohu před zahájením další. V takovém případě by aktér zpracovával úlohy postupně (sekvenčně). Případně může jednotlivý aktér ve vhodnou chvíli střídavě přepínat mezi úlohami. Jediný agent může dokončit všechny úlohy přibližně ve stejnou dobu. Otázkou je, zda je přepínání pro dané úkoly efektivnější. V tomto případě jsou úlohy zpracovávány souběžně, ale ne paralelně.

Efektivnější může být, když je k dispozici více agentů, kteří jsou schopni zpracovat více úloh. V tomto případě musí být více agentů schopno postupovat na úlohách současně, aniž by se navzájem rušili. Úlohy by se zpracovávaly souběžně a také paralelně, takže by byly dokončeny rychleji.

OBRÁZEK: Mějme více úkolů, které je třeba zpracovat. Jeden aktér může plnit úkoly jeden po druhém, tedy sekvenčně. Případně může jediný aktér přepínat mezi úlohami, které jsou zpracovávány souběžně. Vidíte, že úlohy mohou zpracovávat 3 agenti. V tomto případě jsou úlohy zpracovávány souběžně a také paralelně.

Někdy může být obtížné rozdělit práci na více úloh, které by mohly být zpracovávány samostatně. Záleží na tom, zda lze vstupy rozdělit do samostatných jednotek, nebo zda více agentů potřebuje současně používat jedinečný zdroj. V takovém případě může u agentů docházet ke sporům (contention). Znamená to, že více agentů chce využít jedinečné zdroje současně, ale pouze jeden z nich může skutečně uspět. Vítěz může zdroj trvale spotřebovávat nebo jej uvolnit pro ostatní, když jej již nepotřebuje. Contention (spor) lze řešit určitou formou synchronizace agentů. Agenti mohou být omezeni ve zpracování svých dílčích úkolů.

Obecně je výhodné snažit se dosáhnout maximální úrovně paralelizace, pokud nám jde o rychlost zpracování úlohy nebo skupiny menších úloh. Z hlediska škálovatelnosti je pro blockchainové sítě vždy výhodnější, pokud je možné dosáhnout vyšší paralelizace, tj. umožnit zpracování více transakcí současně. Může však být nutné vypořádat se se spory o zdroje a mnoha dalšími aspekty.

Nelze jednoznačně říci, že paralelizace je vždy nejlepším možným řešením. Souběžnost může mít v některých specifických případech své výhody. Zejména pokud je zapotřebí nějaká forma synchronizace, aby se předešlo problémům se spory o zdroje. Neexistuje nic takového jako nejlepší univerzální řešení. Spíše můžeme hovořit o vhodnějším řešení pro konkrétní problém.

Vysvětleme si pojem determinismus. Deterministický algoritmus je algoritmus, který při zadání konkrétního vstupu vždy vytvoří stejný výstup, přičemž se vždy projde stejnou posloupností stavů.

Z pohledu uživatelů to znamená, že mohou odhadnout nebo dokonce předem vědět, jaký výsledek mohou očekávat po vložení konkrétních vstupů. Pokud například do kalkulačky zadáte operaci 5+5, předem očekáváte, že výsledkem bude 10. Jakýkoli jiný výsledek by byl chybou. Vývojáři se snaží vytvářet systémy tak, aby byly co nejvíce deterministické, protože to zaručuje vysokou úroveň spolehlivosti, a tedy i vysoký uživatelský komfort.

V kontextu blockchainu chtějí uživatelé mít možnost předem předvídat výsledek poslání transakce. Determinismus znamená, že když uživatel vytváří transakci, chce, aby se transakce s nastaveným poplatkem dostala do bloku co nejdříve a měla očekávaný výsledek. Stejná očekávání mají uživatelé i v případě validace skriptů a provádění chytrých kontraktů. Když je transakce odeslána, neměla by selhat a uživatel by neměl platit za transakci, která selže.

Při návrhu účetního modelu spolu se způsobem, jakým mají být chytré kontrakty zpracovávány, je důležité předvídat podmínky, za kterých může dojít k neurčitosti. Je důležité pochopit důvody, které k indeterminismu (neurčitosti) vedou, a pokusit se navrhnout systém, ve kterém se mu lze vyhnout nebo se bude vyskytovat minimálně. Vývojáři decentralizovaných aplikací by měli mít k dispozici nástroje, které jim pomohou vytvářet programy, které se chovají předvídatelně a jsou bezpečné.

Jedním z rizik pro aplikace je přístup k proměnlivým datům účetní knihy, tj. datům, která se mohou neustále měnit. Pokud výsledek transakce nebo chytré smlouvy závisí na stavu proměnlivých dat, může během provádění dojít k neurčitosti. Vždy je výhodné, když je zpracování operací co nejvíce izolováno od svého okolí (nepoužívat externí mutabilní data) a závisí pouze na lokálních datech.

Každá operace je vždy do určité míry závislá na svém okolí. Otázkou je, do jaké míry může prostředí ovlivnit výsledek operace a jakým způsobem lze prostředí ovlivnit. Pokud je útočník schopen měnit mutovatelná data ledgeru, může ovlivnit výsledek transakcí a provádění chytrých kontraktů a získat tak osobní profit. Návrh systému by měl možnost útoků minimalizovat.

Stručná historie vývoje účetních modelů

Začněme nejprve u Bitcoinu, který jako první přišel s modelem UTXO. Výhodou UTXO je, že výpočet při ověřování transakcí se provádí off-chain. Transakce jsou jak výsledkem výpočtu (lokálního ověření), tak důkazem. Transakce stačí uložit do blockchainu a není třeba se dále zabývat stavy a jejich případným ukládáním.

Vstupy transakcí jsou vždy existující nespotřebované UTXO a pro uzel je snadné je ověřit. To znamená, že stejnou transakci, respektive stejné vstupy, nelze použít dvakrát. Ověřování je snadné, protože probíhá v rámci bloku, což je prostor s definovanou hranicí. Pokus o druhé utracení stejného vstupu je snadno odhalen a nebude přijat. Transakce lze zpracovávat paralelně, protože nezávisí na žádném vnějším stavu.

Model UTXO v Bitcoinu má velmi slabou programovatelnost. Je téměř nemožné vytvořit složitý výpočet. Pokus o vytvoření stavového kontraktu nad modelem UTXO často vede k vysokým nárokům na úložiště a nízkému využití stavu. Každý vstup vyžaduje jeden “svědecký” (witness) skript a každý výstup vyžaduje jeden zamykací skript. S rostoucím počtem UTXO tedy roste i počet souvisejících skriptů. Výpočetní výkon potřebný pro ověřování skriptů spolu s potřebou ukládat skripty a související data zvyšují nároky na zdroje, a tedy i náklady.

Ethereum jako první přišlo s modelem založeným na účtech. Ethereum umožnilo napsat malý program se složitou logikou zvaný inteligentní kontrakt. Transakce jsou interpretovány jako události, které mění globální stav. Ethereum Virtual Machine (EVM) vypočítává výsledek přechodu těchto událostí do jiného stavu na základě předchozího stavu blockchainu.

To je důležitý bod, protože předchozí stav se stává nedílnou součástí aktuálního výpočtu nového globálního stavu. Jinými slovy, správnost aktuálního výpočtu závisí na minulém. Transakce (vstupní data pro výpočet), které ovlivňují stav blockchainu, jsou syntakticky odděleny od výsledku transakcí (výstupních dat).

Globální stav je uložen lokálně v uzlech a není přenášen v blocích. Uzly dosahují většinového konsenzu o novém globálním stavu tak, že lokálně provedou vlastní výpočet globálního stavu na základě transakcí (událostí) a poté porovnají svůj výsledek s přijatým výsledkem (State-Root). Jinými slovy, všechny poctivé uzly by měly po lokálním výpočtu získat stejný State-Root jako ten navržený. To je jediný způsob přechodu do nového globálního stavu v rámci celé sítě.

OBRÁZEK: Uzel zpracoval 3 transakce (události) a přešel z globálního stavu N do stavu N+3. Poté vytvořil nový blok s State-Root. Všechny uzly v síti by měly po zpracování transakcí vypočítat stejný State-Root.

V modelu založeném na účtech jsou všechny účty stavové. To znamená, že v době výpočtu přechodu do nového stavu (zpracování chytrého kontraktu) je globální stav uzamčen, tj. neměnný. Vývojáři mají k dispozici určitou abstrakci, která usnadňuje vývoj chytrých smluv. Mohou pracovat se všemi zůstatky a interagovat s nimi. Na základě vypočteného výsledku se vytvoří nový globální stav, který se před dalším výpočtem, jehož výsledkem bude další nový stav, opět uzamkne. Mezi jednotlivými stavy existuje posloupnost přechodů.

Výhodou je, že vývojáři mohou pracovat s libovolným účtem (zůstatkem), když je globální stav uzamčen. To znamená, že v rámci jednoho bloku je možné pracovat s konkrétním účtem vícekrát. To je možné díky sekvenčnímu zpracování transakcí a smluv. Jinými slovy, Ethereum je dobré v souběžnosti.

Tento design je přívětivý pro vývojáře, protože se s ním snadno pracuje. Na druhou stranu vývojáři nemohou kontrolovat pořadí zpracování transakcí a kontraktů, protože to je v rukou producentů bloků a uživatelů, kteří stanovují poplatky. Vývojáři tak musí počítat s mnoha možnými výsledky a pokusy o útok. To může představovat výzvu.

Dodržování posloupnosti je důležité, protože je součástí obrany proti útoku dvojího utracení. Každý účet má hodnotu “nonce”, která je obsažena v každé transakci. Při každé nové transakci z daného účtu se hodnota nonce inkrementuje. Tento mechanismus zabraňuje paralelnímu zpracování transakcí. Pokud první z několika transakcí určitého účtu selže a není zahrnuta do bloku, selžou i následující transakce.

Je důležité si uvědomit, že transakce (události) na sobě závisí a záleží na jejich pořadí v bloku. Když uzel obdrží nový blok, přijme jej pouze v případě, že vypočítá stejný State-Root, který je v bloku navržen. K tomu dojde pouze v případě, že je dodrženo pořadí zpracovávaných událostí, tj. stejná posloupnost přechodů.

Jednoduchou transakci v modelu založeném na účtech lze chápat jako požadavek na změnu zůstatků dvou uživatelů. Transakce je událost, která mění globální stav, nikoli konkrétní vstup a výstup. Proto musí být transakce vyhodnocena z hlediska správnosti v kontextu předchozího stavu. To platí i pro všechny ostatní aplikace a protokoly, které jsou postaveny nad EVM.

Uživatelé při zadávání nových transakcí reagují na určitý stav, například na cenu aktiva. Co uživatelé nemohou příliš ovlivnit, je očekávané umístění transakce v rámci posloupnosti přechodů v bloku. To může být problém u složitějších transakcí, které pracují s předem definovanými podmínkami, protože nelze předem zaručit, že navrhovaný přechod stavu bude při pokusu o zařazení stále platný. Uživatel nemá nikdy jistotu a nemůže si předem lokálně ověřit, že jeho transakce bude do bloku zařazena. V důsledku toho může transakce selhat navzdory zaplacenému transakčnímu poplatku. Výsledek transakcí má vyšší míru nejistoty a není deterministický.

Neúspěšné transakce jsou důsledkem globálního stavu (mutovatelných sdílených dat). Více stran může chtít předložit transakce, které změní globální stav určitým způsobem. Změněný globální stav však může zabránit zpracování dalších předložených transakcí. Jinými slovy, zpracována by mohla být pouze první předložená transakce v daném čase nebo za určitých podmínek. Ostatní transakce by mohly selhat. To komplikuje sestavování inteligentních kontraktů a lze to považovat za prostor pro útoky.

Uveďme si konkrétní příklad. Uživatel Bob může sestavit transakci na základě stavu konkrétních zůstatků, které v daném okamžiku vidí. Tyto zůstatky však mohly být změněny transakcí Alice, která byla neočekávaně umístěna před transakcí Boba (Alice mohla použít vyšší poplatek nebo se těžař rozhodl umístit transakci Alice před transakci Boba, protože poplatky byly stejné). V okamžiku, kdy je vložena Bobova transakce, je globální stav jiný než ten, který vzal v úvahu Bob. Tato změna globálního stavu může způsobit selhání transakce nebo v horším případě může vést k nepředvídatelnému stavu.

Shrňme si to. Model založený na účtech, jak jej implementuje Ethereum, má pro vývojáře aplikací tu výhodu, že se nemusí starat o souběžnost. Vývojáři mohou volně pracovat s uživatelskými účty a měnit jejich zůstatek. Je zajištěno, že k zůstatkům se přistupuje jednotlivě podle toho, jak to vyžadují události, takže je menší riziko, že dva agenti budou přistupovat ke stejnému zůstatku ve stejnou dobu. Návrh aplikace je tedy poměrně snadný. Model založený na účtech umožňuje uživatelům přistupovat k jednomu účtu vícekrát v rámci jednoho bloku. To znamená, že Alice může v rámci jedné transakce poslat ETH ze svého účtu Bobovi a v rámci jiné transakce poslat ETH také Carol. Obě transakce mohou být ve stejném bloku.

Nevýhodou je již zmíněná složitost paralelizace, časté neúspěšné transakce a nutnost platit poplatek i za neúspěšné transakce. Kvůli pořadí transakcí navíc vzniká problém známý jako Miner Extractable Value (MEV).

Výhody E-UTXO

Cardano používá model Extended UTXO, zkráceně EUTXO. Účelem modelu EUTXO je podporovat vyšší expresivitu programovatelnosti při zachování všech výhod modelu UTXO Bitcoinu. Rozšířený model UTXO je pro Cardano důležitý, protože chce být více než jen transakční sítí. Cardano je platforma, takže je důležité umožnit vývojářům vytvářet složitější funkce. Toho je dosaženo prostřednictvím chytrých kontraktů. V případě Cardana je přesnější mluvit o validátorových skriptech. V textu můžeme tyto pojmy používat zaměnitelně, ale jde o totéž.

EUTXO nabízí oproti modelu založenému na účtech některé výhody. Zejména větší bezpečnost při provádění chytrých smluv, předvídatelnost poplatků, lokální ověření zajišťující, že transakce budou po odeslání přijaty, a přirozeně fragmentovaný stav blockchainu. To umožňuje paralelizaci při zpracování transakcí, což má pozitivní vliv na škálovatelnost. Paralelizace je důležitá také pro provádění chytrých smluv. Stejně jako transakce mohou být i chytré kontrakty prováděny nezávisle, tj. paralelně.

Při zpracování chytrých kontraktů nezáleží na pořadí v bloku, není třeba brát v úvahu výsledky provádění ostatních kontraktů v bloku, takže samotné provádění lze považovat za bezpečnější. Jinými slovy, protože jednotlivé výsledky provádění chytrých smluv jsou na sobě nezávislé a neexistuje žádný sdílený mutovatelný (globální) stav, je zde menší prostor pro útoky.

Je důležité poznamenat, že škálovatelnost decentralizovaných aplikací je založena na možnostech účetního modelu. Obecně lze chytré smlouvy a jejich provádění považovat za vrstvu, která závisí na schopnostech blockchainu.

Možnosti paralelizace vycházejí z původního návrhu UTXO, kde je každý existující nespotřebovaný UTXO tvořen posloupností předchozích transakcí. S každým UTXO lze pracovat samostatně. Neexistuje nic takového jako globální stav, který by bylo třeba brát v úvahu při zpracování a ověřování EUTXO. Důležitý je pouze lokální stav. To znamená, že výsledek transakce závisí pouze na použití UTXO, což jsou neměnné objekty na jedno použití, které fungují jako vstupy transakcí, které budou produkovat výstupy.

OBRÁZEK: Uzel Cardano zpracoval 3 běžné transakce a 3 skriptové transakce. Poté vytvořil nový blok. Transakce jsou na sobě nezávislé a lze je zpracovávat a ověřovat paralelně.

Každá transakce může spotřebovat jedno nebo více EUTXO, čímž se vytvoří nové EUTXO, které budou mít stejnou celkovou hodnotu. Jediný způsob, jak může transakce ovlivnit účinek jiné transakce aplikované v ledgeru, je utratit stejné EUTXO, jaké se pokusí utratit pozdější transakce, a tím způsobit, že ji uzel odmítne.

Pokud transakce projde lokální validací, může si být uživatel téměř jistý, že se transakce dostane do nového bloku. Transakce v modelu EUTXO jsou na sobě nezávislé a jsou deterministické, což znamená, že transakce s velkou pravděpodobností neselže. To platí i pro validaci skriptů Plutus. Uživatelé mohou lokálně zkontrolovat, zda lze skript Plutus odeslat a provést on-chain. Tím je zajištěno, že se poplatky nikdy neztratí. Je však třeba dodržovat jedno pravidlo, a sice že každé EUTXO lze utratit pouze jednou a jako celek v rámci jednoho bloku.

Utracení UTXO musí být přijato celou sítí v rámci přidání nového bloku. To znamená, že příjemce UTXO jej může utratit pouze v dalším bloku. Nikoliv ve stejném bloku, ve kterém bylo UTXO přijato. Přidání nového bloku lze považovat za přechod stavu blockchainu Cardano. V samotných blocích jsou však jednotlivé transakce a UTXO na sobě nezávislé.

Model EUTXO je determinističtější než model založený na účtech, ale transakce může být přesto odmítnuta. Odmítnutí znamená, že přestože je transakce správně sestavena, nemůže být použita v blockchainu. Pokud se tak stane, transakce nemá žádný vliv na stav blockchainu, takže se neplatí žádné poplatky. K odmítnutí transakce dochází v případě sporu (contention). To znamená, že se stav blockchainu změnil přibližně ve stejnou dobu, kdy uživatel lokálně zkonstruoval transakci. Lokální ověření proběhlo, ale stav blockchainu je v okamžiku podání transakce již jiný. Determinismus zajišťuje, že kdykoli je transakce přijata, bude mít na stav hlavní knihy pouze předvídatelné účinky. Jinými slovy, bude mít na stav hlavní knihy stejný vliv jako při konstrukci a lokální validaci.

Pro vývojáře může být obtížnější vytvořit validační skript, protože se musí sám vypořádat se souběžností. Transakce se mohou dostat do konfliktu, pokud závisí na stejném EUTXO ve stejnou dobu. Pokud by například několik EUTXO bylo uzamčeno inteligentním kontraktem, pak s nimi může uvnitř jednoho bloku interagovat pouze jeden agent. Všimněte si, že toto omezení se vztahuje pouze na EUTXO. Různí agenti mohou interagovat s jinými chytrými kontrakty, aniž by došlo k selhání souběhu. Chytrý kontrakt může pracovat s řadou různých UTXO, které tvoří jeho aktuální stav, a off-chain metadaty, která umožňují interpretaci těchto UTXO.

OBRÁZEK: Souběžné a paralelní zpracování. Agenti mohou využívat více EUTXO najednou. Když chtějí spotřebovat stejný EUTXO, mohou se setkat s konfliktem.

Paralelizace neboli schopnost provádět více nezávislých operací současně je důležitou vlastností z hlediska celkového výkonu a škálovatelnosti sítě. Globální stav modelu založeného na účtech omezuje možnosti škálovatelnosti, protože je velmi obtížné dosáhnout paralelizace při zpracování transakcí a také při provádění inteligentních kontraktů. S modelem EUTXO lze dosáhnout vyšší úrovně souběžnosti, což otevírá dveře ke zvýšení škálovatelnosti.

Podívejme se, co je nového na modelu EUTXO ve srovnání s modelem UTXO, který využívá Bitcoin. Zpracování transakce v síti Cardano zahrnuje ověření požadované akce. Uzel ověřuje, zda je schopen provést požadovanou akci a zda autor transakce poskytl relevantní údaje/vstupy.

Běžná akce se týká běžných transakcí, které mají v úmyslu utratit EUTXO, jež jsou uzamčeny veřejným klíčem. Uzel ověří, že autor transakce poskytl digitální podpis s příslušným soukromým klíčem. Akce, tj. spotřebování EUTXO, se provede, pokud je ověření úspěšné. Oproti Bitcoinu zde zatím není nic nového.

Další akcí je validace transakcí, které mají v úmyslu utratit EUTXO, jež jsou uzamčeny adresou skriptu.

Skript je program (kus kódu), který rozhoduje o tom, zda transakce, která utrácí EUTXO, je k tomu oprávněna. Skript obsahuje funkce, jejichž výsledkem je buď True, nebo False. Pro ověření transakce uzel vyvolá interpret skriptu, což je program, který dokáže přeložit a spustit kód skriptu Plutus. Interpret provede skript, jehož hash byl vytvořen podle adresy, na které jsou uzamčeny UTXO. Jinými slovy, když je EUTXO uzamčeno skriptem Plutus, je kód skriptu tohoto EUTXO spojen s jeho adresou.

OBRÁZEK: Uzel obdrží transakci s akcí na utracení EUTXO, která je uzamčena adresou skriptu.

Podívejme se, co je na EUTXO ve srovnání s Bitcoinem skutečně inovativní, kromě vyšší expresivity programovatelnosti, kterou Plutus umožňuje.

Rozšířené UTXO umožňuje uživatelům volitelně přidávat do UTXO libovolná uživatelská data ve formátu podobném JSON. Tato data se nazývají Datum. Datum umožní vývojářům dát skriptům funkcionalitu podobnou stavu. Uživatelská data lze považovat za lokální stav skriptu. Tento stav má pouze lokální platnost, protože je spojen s konkrétním UTXO. Využití plného potenciálu Datum je na vývojářích.

Transakce mohou nést argumenty specifické pro uživatele, kterým se říká Redeemer. Na Redeemer lze pohlížet jako na záměr autora transakce, jak utratit UTXO. Redeemer mohou vývojáři decentralizovaných aplikací využít k různým účelům.

Mezi Datumem a Redeemerem obvykle existuje vazba, která závisí na konkrétní funkcionalitě konkrétní aplikace. Při ověřování transakce pracuje validační skript s Datumem, Redeemerem a kontextem, který obsahuje údaje o transakci. Skript obsahuje podmínky, které při jejich splnění umožňují spotřebovat UTXO. Datum, Redeemer a kontext transakce jsou data, která jsou vstupem do skriptu.

OBRÁZEK: Na základě vstupních dat skript rozhodne, zda lze EUTXO spotřebovat.

Aby bylo možné utratit EUTXO, které jsou uzamčeny skriptem, je nejprve nutné dostat skript do blockchainu. Odemčení UTXO bude záviset na skriptu, takže transakce bude obsahovat skript a také UTXO, které mají být uzamčeny.

Vývojáři (nebo jejich aplikace) napíší on-chain kód Plutus a zabalí jej do speciálního formátu. Poté je třeba vytvořit transakci, do které bude skript Plutus vložen. Jakmile je transakce uložena v blockchainu, lze odeslat další transakci, která zahájí provádění skriptu. Transakci lze považovat za zprávu pro skript.

Vývojáři rozdělují aplikace na on-chain a off-chain kód. Off-chain kód může být součástí peněženky, nebo se může jednat o decentralizovanou aplikaci (DEX). Off-chain část aplikace může vytvořit transakci, která obsahuje on-chain skript a EUTXO, které mají být uzamčeny. Pro každé EUTXO je třeba zadat hash Datumu. Uživatel musí transakci podepsat. Po odeslání transakce a jejím přijetí sítí budou EUTXO uzamčeny skriptem.

OBRÁZEK: Transakce Plutus obsahuje skript validátoru a přidává datum do EUTXO. Po zařazení transakce do bloku bude EUTXO uzamčeno skriptem.

Validace skriptu je mnohem náročnější na zdroje než validace běžné transakce. Jedním ze zdrojů neurčitosti může být velikost poplatků za provedení chytrého kontraktu/skriptu. V případě Cardano je rozpočet na provedení skriptu součástí transakce a přesnou výši poplatku je možné vypočítat lokálně předem. Interpret skriptu sleduje spotřebu prostředků během provádění skriptu v kontextu rozpočtu. Pokud je rozpočet na provedení vyčerpán, vyhodnocování skriptu se zastaví a výsledkem je False. Hodnota False znamená, že EUTXO nebude spotřebováno.

Všimněte si, že skript Plutus pracuje pouze se stavem, který je spojen s EUTXO, a dále s daty, která obdrží v transakci. Provádění skriptu nezávisí na ničem jiném. Jediné, co se z pohledu účetní knihy na globální úrovni změní, je přesun EUTXO z adres na jiné adresy s každým nově přidaným blokem.

Stejný kontrakt lze použít k uzamčení mincí Alice a Boba. Provedení skriptu pro Aliciny mince nemá žádný vliv na provedení skriptu pro Bobovy mince, protože se jedná o dvě nezávislá provedení pro samostatné EUTXO. Výsledek obou samostatných provedení závisí na lokálních stavech.

Pro interakci se skriptem je vytvořena výdajová transakce (transakce zpráv). Vstupem transakce může být EUTXO, které je uzamčeno skriptem. Výdajová transakce vyvolá interpret skriptu za účelem ověření skriptu a odemknutí EUTXO, pokud jsou splněny podmínky. Odemčené EUTXO se tak přenese na novou adresu.

OBRÁZEK: Aby bylo možné spotřebovat EUTXO z bilance aplikace, musí interpret Plutu spustit skript Plutu spojený s EUTXO. Skript používá jako vstup Datum, Redeemer a kontext transakce. Výsledkem provedení je True, takže EUTXO může být spotřebováno. 12 ADA je odeslán na Bobovu adresu.

Některé aplikace mohou potřebovat pracovat s globálním stavem ve více EUTXO a mohou k tomu použít Datum. Určitý druh globálního stavu je dosažitelný v rámci konkrétního návrhu protokolu. Návrháři protokolů si musí být vědomi toho, že pokud jsou EUTXO uzamčeny skriptem, může s nimi uvnitř jednoho bloku interagovat pouze jeden agent. To může vyžadovat určitý druh synchronizace mezi agenty.

Ilustrujme si to na příkladu. Pooly likvidity, které používá AMM DEX, jsou sdílené zdroje, protože uživatelé je chtějí používat současně (v rámci jednoho bloku). Každý pool likvidity obsahuje sadu EUTXO. Dostupné EUTXO jsou tedy také sdílené zdroje, protože pokud si agent nějakým dohodnutým způsobem nevyhradí konkrétní EUTXO pro sebe, jsou k dispozici všem ostatním.

Aplikační algoritmus musí zajistit, aby při sestavování transakcí jednotliví agenti nesoupeřili o EUTXO v poolu. Transakce, které chtějí spotřebovat konkrétní EUTXO, jsou z hlediska validace na sobě nezávislé. Závislost však existuje, protože více agentů může chtít spotřebovat stejný prostředek (stejný EUTXO) ve stejnou dobu, aby vytvořili transakci. Jinými slovy, agenti chtějí pracovat souběžně. Jedním z řešení, které se v současné době používá, jsou hromadné transakce. Agenti vyhledávají vhodné požadavky UTXO, které chtějí komunikovat s konkrétním poolem likvidity, aby splnili požadovanou výměnu. Agenti tak činí s ohledem na všechny ostatní dostupné požadavky na swap a vybrané swapy vloží do jedné velké hromadné transakce. Při vytváření dávkové transakce agenti vědí, jaké EUTXO již byly použity. Mohou tak zajistit, aby konkrétní EUTXO nebylo v rámci dávkové transakce použito dvakrát.

Závěr

Nejlepší na Cardanu je, že ho tým neustále vylepšuje, čímž se postupně zvyšují jeho schopnosti. V době psaní tohoto článku je před námi hard-fork Vasil, který do Cardana přinese mnoho vylepšení v oblasti skriptů. Konkrétně se jedná o Reference Inputs (CIP-31), Inline Datums (CIP-32), Reference Scripts (CIP-33), and Collateral Outputs (CIP-40). Všechna tato vylepšení poskytnou vývojářům více možností při navrhování jejich aplikací.