Autor: @Web3Mario

Abstrakt: V návaznosti na předchozí článek o zavádění technologie TON jsem v tomto období do hloubky prostudoval oficiální vývojové dokumenty TON, mám pocit, že stále existují určité překážky v učení. Současný obsah dokumentů se zdá být spíše interním vývojem dokument, pro nový základní vývoj Není to příliš přátelské ke čtenářům, takže se snažím utřídit sérii článků o vývoji projektu TON Chain na základě své vlastní studijní trajektorie. Doufám, že to může být užitečné pro každého začal s vývojem TON DApp. Pokud jsou v psaní nějaké chyby, můžete mě opravit a učit se společně.

Jaké jsou rozdíly mezi vývojem NFT v EVM a vývojem NFT na TON Chain?

Vydání FT nebo NFT je obvykle tou nejzákladnější potřebou pro vývojáře DApp. Takže to také používám jako vstupní bod pro učení. Nejprve pochopme následující rozdíly mezi vývojem NFT v technologickém zásobníku EVM a v řetězci TON. NFT založené na EVM se obvykle rozhodnou zdědit standard ERC-721. Takzvaný NFT označuje nedělitelný typ šifrovaného aktiva a každé aktivum je jedinečné, to znamená, že má určité exkluzivní vlastnosti. ERC-721 je běžné vývojové paradigma pro tento typ aktiv. Podívejme se na to, jaké funkce musí implementovat běžná smlouva ERC721 a jaké informace se zaznamenávají. Na obrázku níže je rozhraní ERC721. Je vidět, že na rozdíl od FT je potřeba v převodním rozhraní zadat tokenId, který má být převeden, spíše než částku. Toto tokenId je také nejzákladnějším projevem jedinečnosti NFT aktiv Samozřejmě, aby bylo možné nést více atributů, jsou ke každému tokenId obvykle zaznamenána metadata. Tato metadata jsou externím odkazem, který ukládá další škálovatelná data NFT, např jako odkazy na obrázky PFP, názvy určitých atributů atd.

Pro vývojáře, kteří jsou obeznámeni se Solidity nebo obeznámeni s objektově orientovaným, je snadné implementovat takovou inteligentní smlouvu. Stačí definovat datové typy požadované ve smlouvě, jako jsou některé vztahy mapování klíčů, a vytvořit odpovídající podle požadovaných funkcí Logika modifikace těchto dat může realizovat NFT.

V TON Chain je však vše jinak. Rozdíl má dva hlavní důvody:

l Ukládání dat v TON je založeno na Cell a Buňka stejného účtu je implementována prostřednictvím orientovaného acyklického grafu. To znamená, že data, která je třeba uložit, nemohou růst bez hranic, protože u orientovaného acyklického grafu je cena dotazu určena hloubkou dat Smlouva uvízla v patové situaci.

l Aby bylo možné dosáhnout vysokého souběžného výkonu, TON opustil architekturu sériového spouštění a místo toho přijal vývojové paradigma speciálně navržené pro paralelismus, model Actor, k rekonstrukci spouštěcího prostředí. To má dopad pouze asynchronně zasíláním tzv. interních zpráv. Všimněte si, že ať už se jedná o typ volání s modifikací stavu nebo pouze pro čtení, tento princip je třeba také dodržovat je třeba pečlivě zvážit, jak zacházet s vrácením dat, pokud selže asynchronní volání.

Samozřejmě, že další technické rozdíly byly podrobně rozebrány v předchozím článku Tento článek doufá, že se zaměří na vývoj chytrých smluv, takže o něm nebude řeč. Výše uvedené dva principy návrhu dělají velký rozdíl mezi vývojem chytrých smluv a EVM v TON. V úvodní diskuzi víme, že smlouva o NFT musí definovat některé vztahy mapování, tedy mapování, aby se ukládala data související s NFT. Nejdůležitější z nich jsou vlastníci. Toto mapování ukládá mapovací vztah adresy vlastníka NFT odpovídající určitému tokenID, který určuje vlastnictví NFT. Protože se jedná o datovou strukturu, která může být teoreticky neomezená, je třeba se jí co nejvíce vyhnout. Proto se oficiálně doporučuje používat jako standard pro sharding existenci neomezených datových struktur. To znamená, že pokud existují podobné požadavky na ukládání dat, použije se místo toho paradigma smlouvy master-slave a data odpovídající každému klíči jsou spravována vytvářením subdodávek. A spravovat globální parametry prostřednictvím hlavní smlouvy nebo pomoci s interakcí interních informací mezi dílčími smlouvami.

To znamená, že i NFT v TON musí být navrženy pomocí podobné architektury. Každý NFT je nezávislá subdodávka, která ukládá exkluzivní data, jako je adresa vlastníka, metadata atd., a řídí celkovou situaci prostřednictvím hlavní smlouvy jako je název NFT, symbol, celková dodávka atd.

Po vyjasnění architektury je dalším krokem vyřešení základních funkčních požadavků Vzhledem k přijetí této smlouvy master-slave,

Proto je nutné vyjasnit, které funkce nese hlavní smlouva a jaké funkce podsmlouva a jaké interní informace se používají ke komunikaci mezi nimi. Zároveň, když dojde k chybě při provádění, jak vrátit předchozí data. Obvykle je před vývojem složitého rozsáhlého projektu nutné předat diagram tříd a vyjasnit si tok informací mezi sebou a pečlivě promyslet logiku rollbacku po selhání interního volání. Samozřejmě, že výše zmíněný vývoj NFT je jednoduchý, ale může také provést podobné ověření.

Naučte se vyvíjet chytré smlouvy TON ze zdrojového kódu

TON se rozhodl navrhnout staticky typovaný jazyk typu C s názvem Func jako jazyk pro vývoj chytrých smluv. Poté se naučíme vyvíjet chytré smlouvy TON ze zdrojového kódu. Vybral jsem si příklad NFT v oficiálním dokumentu TON Zainteresovaní přátelé si to mohou ověřit sami. V tomto případě je implementován jednoduchý příklad TON NFT. Podívejme se na strukturu smluv, která je rozdělena na dvě funkční smlouvy a tři potřebné knihovny.

Tyto dvě hlavní funkční smlouvy jsou navrženy podle výše uvedených principů Nejprve se podívejme na kód hlavní smlouvy nft-collection:

To představuje první znalostní bod, jak trvale ukládat data v TON smart kontraktech Víme, že trvalé ukládání dat v Solidity automaticky řeší EVM podle typu parametrů Normálně to budou stavové proměnné automaticky přetrvává a ukládá se na základě nejnovější hodnoty po spuštění a vývojáři tento proces nemusí brát v úvahu. Ale to není případ Func Vývojáři musí sami implementovat odpovídající logiku zpracování Tato situace je poněkud podobná potřebě zvážit proces GC v C a C++, ale jiné nové vývojové jazyky obvykle tuto část automatizují. logika. Podívejme se na kód Nejprve si představíme některé požadované knihovny a pak vidíme, že první funkce load_data se používá k načtení trvale uložených dat. Všimněte si toho to se provádí standardem Implementováno knihovnou stdlib.fc, některé z těchto funkcí lze obvykle použít jako systémové funkce.

Typ návratové hodnoty této funkce je buňka, což je typ buňky v TVM. V předchozím úvodu již víme, že všechna perzistentní data v blockchainu TON jsou uložena ve stromu buněk. Každá buňka má až 1023 bitů libovolných dat a až čtyři odkazy na jiné buňky. Buňky se používají jako paměť v zásobníku TVM. To, co je uloženo v buňce, jsou kompaktně zakódovaná data K získání specifických dat ve formátu prostého textu je třeba buňku převést na typ nazývaný řez. Buňku lze převést na typ řezu pomocí funkce begin_parse a poté lze data v buňce získat načtením datových bitů z řezu a odkazů na jiné buňky. Všimněte si, že tato metoda volání na řádku 15 je syntaktický cukr ve funkci func a můžete přímo volat druhou funkci, která vrací hodnotu první funkce. A nakonec načtěte odpovídající data v pořadí podle pořadí perzistence dat. Všimněte si, že tento proces se liší od solidity a není volán na základě hashmap, takže pořadí volání nemůže být zpackáno.

Ve funkci save_data je logika podobná, až na to, že se jedná o opačný proces, který zavádí další znalostní bod, nový typ builder, což je typ cell builderu. Datové bity a odkazy na jiné buňky mohou být uloženy v builderech, které pak mohou být finalizovány do nových buněk. Nejprve vytvořte sestavu pomocí standardní funkce begin_cell a postupně ukládejte související funkce prostřednictvím funkcí souvisejících s ukládáním Všimněte si, že výše uvedený příkaz volání musí být konzistentní s pořadím úložiště zde. Nakonec je dokončena konstrukce nové buňky pomocí end_cell. V tomto okamžiku je buňka spravována v paměti. Nakonec lze dokončit trvalé ukládání buňky.

Dále se podívejme na funkce související s podnikáním Nejprve je třeba představit další znalostní bod, jak vytvořit novou smlouvu prostřednictvím smlouvy, která bude často používána v právě představené architektuře master-slave. Víme, že v TONu jsou hovory mezi smart kontrakty realizovány zasíláním interních zpráv. Toho je dosaženo prostřednictvím zprávy nazvané send_raw_message Všimněte si, že prvním parametrem je buňka zakódovaná ve zprávě a druhým parametrem je identifikační bit, který se používá k označení rozdílu ve způsobu provádění transakce v TON jsou aktuálně 3 režimy zpráv a 3 příznaky zpráv pro způsob provedení odeslání zprávy. Jeden režim lze zkombinovat s více (možná žádnými) příznaky pro získání požadovaného režimu. Kombinovat znamená pouze vyplnit součet jejich hodnot. Tabulka popisu režimů a příznaků je uvedena níže:

Podívejme se tedy na první hlavní funkci deploy_nft_item Jak název napovídá, jedná se o funkci používanou k vytvoření nebo přetypování nové instance NFT příznakový bit 1 používá jako poplatek za plyn za toto provedení pouze poplatek uvedený v kódování. Po výše uvedeném úvodu si snadno uvědomíme, že toto pravidlo kódování by mělo odpovídat způsobu vytvoření nového smart kontraktu.

Pojďme se tedy podívat, jak je implementován.

Podívejme se přímo na řádek 51. Výše ​​uvedené dvě funkce jsou pomocné funkce sloužící ke generování informací požadovaných pro zprávu, takže se na to podíváme později. Jedná se o proces kódování pro vytváření interních zpráv smart kontraktu uprostřed jsou vlastně Některé identifikační bity se používají k popisu požadavků na interní zprávu Další znalostní bod je zde představen TON pro popis způsobu provedení zprávy zvolil binární jazyk TL-B a podle něj jej implementuje nastavení různých příznakových bitů Pro interní informace o určitých specifických funkcích jsou dva nejjednodušší scénáře použití, které lze považovat za vytvoření nové smlouvy a nasazená volání funkcí smlouvy. Metoda na řádku 51 odpovídá předchozí, čímž se vytvoří nová položková smlouva nft, která je specifikována především prostřednictvím řádků 55, 56 a 57. Za prvé, velká řada čísel na řádku 55 je řada identifikačních bitů. Všimněte si, že prvním vstupním parametrem store_uint je hodnota a druhým je bitová délka, která určuje, zda je interní zpráva vytvořena smlouvou. , poslední tři označovací bity a odpovídající Bit binární hodnoty je 111 (desítková hodnota je 4+2+1), z nichž první dva indikují, že zpráva bude doprovázena daty StateInit Tato data jsou zdrojovým kódem novou smlouvu a údaje potřebné pro inicializaci. Druhý příznakový bit označuje interní přílohu zprávy, to znamená, že se očekává provedení příslušné logiky a požadovaných parametrů. Uvidíte tedy, že na řádku 66 kódu není nastaven třímístný údaj, který označuje volání funkce nasazené smlouvy. Podrobná pravidla kódování naleznete zde.

Kódovací pravidla StateInit pak odpovídají 49 řádkům kódu, vypočítaným pomocí create_nft_item_state_init Všimněte si, že kódování dat stateinit se řídí také zavedeným pravidlem kódování TL-B, kromě některých příznakových bitů zahrnuje hlavně dvě části nové smlouvy kód a A inicializovat data. Pořadí kódování dat musí být konzistentní s pořadím ukládání buněk perzistence specifikovaným v nové smlouvě. Jak můžete vidět na řádku 36, inicializační data zahrnují item_index, který je podobný tokenId v ERC721, a aktuální adresu smlouvy vrácenou standardní funkcí moje_adresa, což je adresa_kolekce Pořadí těchto dat je konzistentní s deklarací v nft-položka.

Další znalostní bod je, že v TON mohou všechny nevygenerované smart kontrakty předem vypočítat své vygenerované adresy. To je podobné jako u funkce create2 v Solidity Generování nových adres v TON se skládá ze dvou částí, identifikátoru pracovního řetězce Bit a hash stateinit. hodnoty jsou spojeny dohromady V předchozím úvodu již víme, že první musí být specifikován, aby odpovídal architektuře nekonečného shardingu TON. V současnosti se jedná o jednotnou hodnotu. Získáno ze standardního funkčního pracovního řetězce. Ten se získá standardní funkcí cell_hash. Takže zpět k tomuto příkladu, count_nft_item_address je funkce, která předem vypočítá adresu nové smlouvy. A vygenerovanou hodnotu zakódujte do zprávy na řádku 53 jako přijímací adresu interní zprávy. nft_content odpovídá inicializačnímu volání vytvořené smlouvy Konkrétní implementace bude představena v dalším článku.

Pokud jde o send_royalty_params, musí se jednat o reakci na interní zprávu požadavku pouze pro čtení V předchozím úvodu jsme zvláště zdůraznili, že interní zpráva v TON obsahuje nejen operace, které mohou upravit data, ale také čtení. tímto způsobem je třeba provést pouze operaci Implementace, takže tato smlouva je taková operace Především je třeba poznamenat, že řádek 67 představuje značku funkce zpětného volání žadatele po odpovědi na požadavek budou vrácená data, kterými jsou požadovaný index položky a odpovídající data.

Dále si představíme další znalostní bod V TON existují pouze dva jednotné vstupy do inteligentních kontraktů, pojmenované recv_internal.

a recv_external, kde první je jednotný vstup pro volání pro všechny interní zprávy a druhý je jednotný vstup pro volání pro všechny externí zprávy Vývojáři potřebují použít metodu podobnou přepínači uvnitř funkce podle požadavků, aby mohli reagovat na různé značky bitů specifikovaných zprávou, značka bit je značka funkce zpětného volání na řádku 67 výše. Zpět k tomuto příkladu nejprve proveďte kontrolu volného místa ve zprávě a poté analyzujte informace ve zprávě. Nejprve analyzujte na řádku 83, abyste získali adresu odesílatele Tento parametr bude použit pro následné kontroly oprávnění zde patří k jiné syntaxi. Nebudu to zde rozvádět. Dále se analyzují příznakové bity operace a poté se odpovídající požadavky zpracují podle různých příznakových bitů. Mezi nimi jsou výše uvedené funkce volány příslušně podle určité logiky. Například odpovězte na požadavek na parametr licenčního poplatku nebo přetypujte nové nft a zvyšte globální index.

Další znalostní bod odpovídá řádku 108. Myslím, že logiku zpracování této funkce můžete také znát jejím pojmenováním. Výjimky jsou vyvolány ve Func prostřednictvím standardní funkce throw_unless je kód chyby, druhým je kontrola bitové booleovské hodnoty, pokud je bit nepravdivý, bude vyvolána výjimka s kódem chyby. V tomto řádku se equal_slices používá k určení, zda je adresa odesílatele analyzovaná výše rovna adrese vlastníka trvalého úložiště smlouvy, a je provedeno rozhodnutí o povolení.

A konečně, aby byla struktura kódu jasnější, byla vyvinuta řada pomocných funkcí, které pomáhají získat informace o perzistenci, které zde nebudou představeny Vývojáři se mohou na tuto strukturu odvolávat při vývoji vlastních inteligentních smluv.

Vývoj DApp v ekosystému TON je opravdu zajímavý a velmi se liší od vývojového paradigmatu EVM, proto prostřednictvím série článků představím, jak vyvíjet DApp v TON Chain. Učte se společně se všemi a chopte se této vlny příležitostí. Můžete se mnou také komunikovat na twitteru a přijít s novými a zajímavými nápady dapp a společně je rozvíjet.