Podobné články

Technická architektura kvantových koček

Quantum Cats je sbírka 3333 nápisů Ordinals, které se v průběhu času vyvíjejí a odhalují různá umělecká díla. Jedná se o vůbec první sbírku Nápisů, které se v průběhu času vyvíjejí, a byla vytvořena v době vysokých poplatků a nepředvídatelného budoucího trhu s poplatky. Toto není článek o estetických přednostech uměleckých děl (myslím, že vypadají skvěle) ani o důvodech, proč se účastnit trhu s nimi; toto je článek o technickém provedení Kvantových koček. Myslím, že technické výzvy, kterým jsme čelili, a techniky, které jsme implementovali, abychom se s těmito výzvami vypořádali, jsou zajímavé a potenciálně užitečné jak pro budoucí tvůrce Ordinals, tak pro ostatní vývojáře aplikací Bitcoin obecně.

Než se pustíme do technických podrobností Kvantových koček, bude užitečné pochopit, jaký zážitek jsme se snažili vytvořit. Uživatelé Ordinals drží inskripce (digitální sběratelské předměty, které jsou implementovány v protokolu Ordinals a jsou převáděny pomocí bitcoinové transakce) v samoobslužných bitcoinových peněženkách, které mají funkce kontroly mincí a konstrukce transakcí, jež umožňují převod konkrétních ordinálů, jakož i podepisování složitějších typů transakcí (jako jsou bezdůvěryhodné nabídky a výměny na tržištích Ordinals). Chtěli jsme vytvořit kolekci Inscription, která by se v průběhu času vyvíjela – přidávala nebo měnila atributy či vlastnosti Kocourů.

Umělecká díla pro Nápisy jsou zveřejňována v řetězci ve svědectví transakce Taproot (ve speciálním kódování zvaném Obálka – software, který si uvědomuje ordinály, analyzuje transakce a hledá tuto obálku, aby našel Nápisy). To znamená, že jakákoli konkrétní data nápisu jsou neměnná a po jejich zveřejnění je nelze změnit (s výjimkou reorganizace). Existuje však několik různých způsobů, jak můžeme zprostředkovat zážitek ze změny uměleckého díla, i když se umělecké dílo ve skutečnosti nikdy nezmění (a ve skutečnosti je skvělé mít přístup ke starému uměleckému dílu, pokud se vám líbí víc!).

Rekurze je funkce ordinálů, kdy jeden nápis může odkazovat na obsah jiného. Můžete například napsat stránku HTML a nechat ji obsahovat obrázky, které jsou v jiných nápisech. Software Ordinals vykresluje stránky HTML v iframech, takže můžete nechat obsah ordinálu sestavit na straně klienta z více nápisů. Nápisy HTML nemohou obsahovat obsah z širšího webu, pouze z jiných nápisů nebo malé sady dalších koncových bodů poskytovaných softwarem ordinals (například existuje koncový bod pro načtení aktuální výšky bloku bitcoinu). To znamená, že všechny rekurzivní nápisy jsou stále na řetězci, jen jsou rozložené, což umožňuje složitelnost a opakované použití společných komponent. Například všechny Kvantové kočky s červeným pozadím mohou odkazovat na jediný nápis obsahující červené pozadí, místo aby všechny musely vkládat stejná data on-chain.

Pokud jeden nápis odkazuje na jiný, činí tak pomocí svého ID nápisu. ID nápisu se skládá z ID bitcoinové transakce, v níž jsou data nápisu odhalena, písmene i a dále z výstupního indexu vytvořeného nápisu. Například nápis 4b31771df21656d2a77e6fa18720a6dd94b04510b9065a7c67250d5c89ad2079i0 je první nápis vytvořený v bitcoinové transakci 4b31771df21656d2a77e6fa18720a6dd94b04510b9065a7c67250d5c89ad2079. To znamená, že pokud napíšete obrázek (například png) a poté napíšete stránku HTML, která obsahuje ID nápisu obrázku v tagu img, můžete nechat nápis HTML vykreslit obsah nápisu obrázku. Pokud nápis HTML odkazuje na nápis obrázku, který ve skutečnosti (zatím) není na řetězci, pak server ordinals vrátí chybu 404 (nenalezen), kterou může nápis HTML v klidu spolknout. Pokud obrazové nápisy předem podepíšeme – ale nebudeme je vysílat do sítě Bitcoin – můžeme získat jejich budoucí ID nápisů (protože se jedná pouze o ID transakce a index) a tato ID nápisů zahrnout do HTML nápisů, které vysíláme . Když si někdo zobrazí nápis HTML, bude schopen vykreslit obsah jeho odkazů, které jsou v řetězci, ale nebude schopen vykreslit předznamenané, ale nevysílané komponenty. Jakmile bude zveřejněno více komponent, bude je HTML nápis automaticky schopen vykreslit. Toto je základní mechanismus, který kolekce Quantum Cats používá k vývoji svých uměleckých děl – předznamenané transakce pro vlastnosti, které jsou postupně odhalovány v průběhu času. Jak uvidíme, správa poplatků a dynamika trhu zavedly složitosti, kvůli nimž Quantum Cats potřebuje některé další vrstvy indirekce a funkce, ale presignované transakce s předem vypočtenými ID transakcí jsou klíčovou vlastností Bitcoinu, která umožnila vznik této kolekce.

Přestože obsah předsignovaného, ale nezveřejněného zápisu není před vysíláním transakce znám, stejné ID zápisu bude mít stejný obsah. Tím vznikl problém: přestože lidé nemohou říct, jaký bude budoucí rys (například pozadí nebo rys těla), budou schopni spočítat, kolikrát se určité ID nápisu vyskytlo, a budou schopni říct, které budoucí rysy jsou více či méně vzácné, a budou moci obchodovat s Kočkami na základě jejich budoucího vývoje. Opravdu jsme chtěli, aby evoluce byly překvapivé a zábavné, a to, že dopředu nevíme, co budoucí evoluce udělají s relativní vzácností různých koček, je velmi zábavné. Proto jsme zavedli vrstvu indirekce: každá kočka odkazuje na předznamenaný (ale nezveřejněný) „Layer Connector“, který mapuje kočku pomocí jedinečného ID na předznamenané umělecké dílo. To například znamená, že každá kočka odkazuje na stejný Layer Connector pro svůj počáteční obrázek na pozadí. Teprve když je tento Layer Connector vysílán do sítě, mohou se lidé dozvědět, která pozadí jsou více či méně častá. Tato technika také umožnila úsporu místa: protože každá kočka odkazuje na identické konektory vrstev, může být HTML pro kočku pro import konektorů vrstev zapsáno jednou a pak na něj odkazuje každý z 3333 nápisů Cat. Ve skutečnosti byl každý nápis Cat zredukován na 109 bajtů: pouze jedinečné ID Cat a značka skriptu pro import logiky pro načtení a vykreslení společné sady konektorů vrstev, vyhledání jedinečného díla pro každou vrstvu podle Cat a vykreslení tohoto díla. Možnost přesunout mapování každé kočky na její umělecké dílo z jednotlivých nápisů koček do společného nápisu a přidání vrstvy předznamenané indirekce nejen vyřešilo únik informací o relativní vzácnosti u znaků, ale také ušetřilo přibližně 5 BTC nákladů na nápisy!

Díky tomuto zavedení nápisů Layer-Connector a faktoringu logiky vykreslování do společné komponenty jsou nyní zapisovány 4 druhy aktiv:

  • Skutečné umělecké dílo pro každý rys v Kočce (obrázek pozadí, nebo tělo, nebo oči)
  • Layer-Connector, který mapuje Kočku podle jejího ID na konkrétní umělecké dílo. Toto mapování se provádí jednou pro každou „vrstvu“ (pozadí, tělo, oči, ústa atd.)
  • Základní logika odesílání a vykreslování. Nazýváme ji „Dispečer“. Je zodpovědný za načtení konektoru vrstvy, vyhledání uměleckého díla pro kočku v konektoru vrstvy, načtení tohoto uměleckého aktiva a jeho následné vykreslení na plátno v pořadí. Toto postupné vykreslování v pořadí je důvodem, proč modelujeme umělecké dílo jako vrstvu.
  • Jednotlivá Kočka, která je distribuována do sběratele. Má velikost 109 bajtů a obsahuje jedinečné ID a odkaz na dispečer, který obsahuje veškerý kód pro vykreslování

V Quantum Cats je několik stovek aktiv uměleckých děl, 40 vrstev (což znamená 40 propojení vrstev), 1 dispečer a 3333 koček. Nápisy 3333 koček odkazují na ID nápisu dispečera, který odkazuje na ID nápisů 40 layer-connectorů, z nichž každý odkazuje na jedno nebo více ID nápisů aktiv uměleckých děl. Tato aktiva jsme předepisovali v opačném pořadí: nejprve jsme vyrenderovali umělecká díla, abychom získali jejich ID nápisů, poté jsme je vyrenderovali do konektorů vrstev a předepisovali je, abychom získali jejich ID nápisů, poté jsme vyrenderovali Dispatcher a předepisovali jej a nakonec jsme sestavili jednotlivé nápisy Cat.

ID nápisů zahrnují ID transakce Bitcoin. ID bitcoinových transakcí jsou funkcí jejich vstupů, výstupů, verze a doby uzamčení. To znamená, že pokud utratíme UTXO, které financuje předpřipravenou transakci, na nějakou jinou transakci, pak už nikdy nebudeme moci znovu vytvořit stejné ID transakce a porušíme náš předpřipravený odkaz na nápis! Abychom tomu předešli, vytvořili jsme UTXO pro financování každé předepsané transakce a pak jsme udržovali databázi, která sledovala, které UTXO bylo přiřazeno k financování které předepsané transakce. Měli jsme také automatické kontroly správnosti, které zajišťovaly, že žádné dva nápisy neutratily stejné UTXO, že každá transakce odevzdání nápisu utratila pouze jí přidělené UTXO a že celkové vstupy a výstupy všech transakcí (včetně poplatků) odpovídaly našim očekáváním. Tyto kontroly probíhaly vždy, když se systém dotkl peněženek nebo klíčů, a dávaly nám jistotu, že se nepodepisuje nic, co by se podepisovat nemělo. Kromě toho jsme používali oddělené peněženky pro různé typy zápisů aktiv, abychom přidali další ochranu proti chybě způsobující dvojí přiřazení UTXO. Vytvořili jsme také testovací svazek, který procházel veškerým podepisováním a zveřejňováním nápisů na regtestu a poté ověřoval, že data, která skončila v řetězci, odpovídají tomu, co bylo v naší databázi v kontrolní rovině.

Předpodepisování transakcí tímto způsobem znamenalo, že jsme museli předem stanovit poplatky, které bude každý nápis platit. Nemůžeme vědět, jaké budou sazby poplatků, až tyto evoluce nakonec odhalíme, takže jsme se rozhodli přednačítat transakce s rozumnou sazbou poplatků a pak vytvořit nástroje, které by v budoucnu poplatky zvýšily, pokud bychom přednačítali příliš nízké (pokud bychom přednačítali vyšší poplatek, než je potřeba, museli bychom s tím prostě žít, takže součástí analýzy zde bylo vybrat sazbu poplatků, která by nám vyhovovala, i kdyby se ukázalo, že jsme přeplatili). Kromě využití služby akcelerátoru transakcí (placení těžaři mimo pásmo za zahrnutí transakce do bloku, i když platí nižší než tržní poplatky) existují dvě techniky, jak zvýšit efektivní sazbu poplatku za transakci: Nahradit poplatek (RBF) a Dítě platí za rodiče (CPFP). RBF spočívá v opětovném vynaložení vstupů transakce na novou transakci, která platí vyšší poplatek. Vzhledem k tomu, že naše aplikace se spoléhá na předem přidělené ID transakce, tato možnost nepřipadala v úvahu. CPFP zahrnuje utrácení nepotvrzeného výstupu transakce v nové transakci, která platí vyšší poplatek než „rodič“. Aby těžaři mohli zachytit poplatky z této „dětské“ transakce, musí zahrnout jak rodiče, tak dítě jako balíček. Efektivní sazba poplatků se nakonec rovná součtu zaplacených poplatků vydělenému celkovou virtuální velikostí balíčku (všechny transakce dohromady). Vzhledem k tomu, že rodičovská transakce není narušena, byl to přesně ten mechanismus navyšování poplatků, který jsme potřebovali.

Zbývající vráska spočívá v tom, že jsme měli potenciálně stovky transakcí, které by bylo třeba poplatkově zvýhodnit. Kromě toho, že je obtížné ručně přesně bumpingovat desítky nebo stovky nepotvrzených transakcí, existují také zásady přenosu, které brání tomu, aby byl sítí přenesen balík větší než 101 KvB (virtuálních kilobajtů) nebo více než 25 transakcí. To znamená, že pokud bychom potřebovali CPFP 50 transakcí, chtěli bychom je všechny provést paralelně, nikoli sériově. Abychom toho dosáhli, vytvořili jsme nástroje, které by:

  • se podíval na seznam nepotvrzených transakcí a pro každou z nich vypočítal náklady na CPFP-bump těchto transakcí na cílovou sazbu poplatků
  • agregoval tyto částky jako výstupy v nové transakci, která utrácela z jediného vstupu na všechny UTXO potřebné k bumpování cílových transakcí paralelně
  • vyzval operátora, aby poslal celkovou požadovanou částku bitcoinů (vypočítal také poplatky za rozdělení transakce) na jedinou adresu
  • jakmile byl vklad přijat, vysílal by transakci, která by rozdělila vklad na jedno UTXO pro každou transakci, kterou je třeba bumpnout
  • Poté by zkonstruoval a vysílal CPFP transakce pro každou z uvízlých transakcí

Tento systém jsme testovali na Regtestu bumpingu až 300 transakcí najednou. Měli jsme také příležitost jej použít, když jsme potřebovali bumpnout poplatky několika transakcí odhalujících propojení vrstev na mainnetu! „Rozdělenou“ transakci si můžete prohlédnout zde: https://mempool.space/tx/2ec4a8708524faf9901c69da8518b632ec31762730218d3b38ff40954cee882f. Každý z těchto výstupů financuje CPFP k bumpnutí transakce odhalení nápisu z 65 na 150 sat/vb

Umělecká aktiva tvořila ~90 % celkových dat projektu. Chtěli jsme oportunisticky zveřejnit všechny nebo co největší část uměleckých děl, když byly poplatky nízké. Ale také jsme nechtěli, aby lidé viděli umění dříve, než budou kočky připraveny k vývoji. Proto jsme se rozhodli umělecká díla zašifrovat a poté zveřejnit dešifrovací klíč pro umělecká díla s konektorem vrstvy (který obsahuje mapování potřebné k tomu, aby kočka získala svůj rys). To nám umožnilo oddělit krok zveřejnění dat od odhalení rysů. To nám umožnilo využít dobu nižších poplatků za hromadné zveřejnění dat a zároveň jsme mohli ukázat světu umělecké dílo v době, která dávala smysl pro sbírku. Mechanika je zde přímočará: před odesláním aktiv uměleckých děl se všechna umělecká díla pro určitou vrstvu (opět si představte pozadí, oči nebo ústa) zašifrují pomocí šifrovacího klíče pro každou vrstvu. Tato zašifrovaná umělecká díla jsou použita v předepsaném nápisu jako proud bajtů. Poté je šifrovací klíč vykreslen do konektoru vrstvy (který je opět předznamenán). Když dispečer načte konektor vrstvy, načte mapování Cat-ID -> umělecký prostředek a také dešifrovací klíč pro danou vrstvu. Když načte umělecké aktivum, získá ho jako pole bajtů a pak pomocí kryptografických knihoven prohlížeče dešifruje umělecké dílo jako png a nakonec ho zapíše na plátno.

Když to dáme dohromady, každá Quantum Cat je malý nápis, který načte společný nápis, který obsahuje kód pro odesílání, dešifrování a vykreslování. Tento kód načte tolik vrstev-konektorů, kolik je jich v řetězci k dispozici (některé z nich nebudou, protože jsou předem podepsané, ale nerozšířené). Poté použije ID nápisů a dešifrovací klíče v těchto konektorech vrstev k načtení zašifrovaných uměleckých děl v jiných nápisech, dešifruje je a poté je vykreslí na plátno. Když potřebujeme tyto předem podepsané nápisy vysílat, použijeme hromadné paralelní transakce CPFP, abychom je zvýšili na správnou sazbu poplatku, aniž bychom se museli předem zavázat k příliš vysokému poplatku. Čistým výsledkem toho všeho je, že uživatelé mají ve své peněžence Kvantovou kočku, která se v průběhu času vyvíjí a získává nové vlastnosti a atributy, a přitom jsou všechna její aktiva v Bitcoinu neměnná.

Existují i další aspekty projektu, které jsme zde nepopsali – jak kód prohlížeče zvládá občasné výpadky při načítání všech těchto aktiv, jak se vypořádat s kurátorstvím vyvíjející se sbírky, jak jsme vůbec zvládli proces vytváření UTXO pro všechna předpřipravená aktiva (to je snadné: je to stejný kód pro rozdělení UTXO s vějířovitým rozdělením, který byl popsán výše pro financování UTXO CPFP). Doufám však, že vás výše uvedená diskuse zaujme a bude vám užitečná buď v projektu inscription, nebo v jiném projektu zahrnujícím presignované transakce.

Tento příspěvek napsal host Rijndael. Vyjádřené názory jsou výhradně jeho vlastní a nemusí nutně odrážet názory společnosti BTC Inc. nebo časopisu Bitcoin Magazine

Share on facebook
Facebook
Share on twitter
Twitter
Share on linkedin
LinkedIn

Diskuze

{{ reviewsTotal }} Review
{{ reviewsTotal }} Reviews
{{ options.labels.newReviewButton }}
{{ userData.canReview.message }}