Původní autor: @Web3 Mario (https://x.com/web3_mario)

V návaznosti na předchozí článek o zavedení 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 dokumentu se zdá být spíše interním vývojovým dokumentem. který je vhodný pro nové vývojáře Není příliš přátelský, a tak jsem se pokusil utřídit sérii článků o vývoji projektu TON Chain na základě mé vlastní studijní trajektorie . 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 často základní 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 TON Chain. NFT založené na EVM se často 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 ERC 721 a jaké informace se zaznamenávají. Na obrázku níže je rozhraní ERC 721. 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 ztělesněním 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 vlastností atd.

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

To však není stejné v řetězci TON. Rozdíl má dva hlavní důvody:

  • Ukládání dat v TON je implementováno na základě buněk a buňky stejného účtu jsou implementovány prostřednictvím směrovaných acyklických grafů. 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 na mrtvém bodě.

  • 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 inteligentních kontraktů v TON a EVM. 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ší jsou vlastníci. Toto mapování ukládá mapovací vztah adresy vlastníka NFT odpovídající určitému ID tokenu, 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 objasnění architektury je dalším krokem vyřešení základních funkčních požadavků Vzhledem k tomu, že je přijata tato metoda master-slave smlouvy, je nutné vyjasnit, které funkce jsou prováděny hlavní smlouvou a které funkce jsou prováděny subdodávkou. a oba jsou předávány přes Jaké interní informace jsou sdělovány a jak vrátit předchozí data, když dojde k chybě provádění. 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 vrácení po selhání interního volání. Výše ​​uvedený vývoj NFT je samozřejmě 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 zásad. 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 je automaticky řešeno EVM podle typu parametrů Normálně stavové proměnné smart kontraktu It budou automaticky zachovány a uloženy na základě nejnovější hodnoty po spuštění a vývojáři nemusí tento proces zvažovat. Ale to není případ Func Vývojáři musí sami implementovat odpovídající logiku zpracování Tato situace je poněkud podobná tomu, jak C a C++ musí zvážit proces GC, ale jiné nové vývojové jazyky tuto část logiky obvykle automatizují. . 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 Chcete-li získat konkrétní data 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ů a odkazů na jiné buňky z řezu. Všimněte si, že volající metoda na řádku 15 je syntaktický cukr ve funkci, která přímo volá druhou funkci na návratovou 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 poté uložte související funkce prostřednictvím funkcí souvisejících s ukládáním Všimněte si, že výše uvedené volání musí být konzistentní s pořadím úložiště zde. Nakonec se end_cell použije k dokončení konstrukce nové buňky. V tomto okamžiku je buňka spravována v paměti. Nakonec může být dokončeno 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 režim provádění odesílání zpráv. 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 s popisem 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á pouze poplatek uvedený v kódování jako poplatek za plyn pro toto provedení. 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 používané pro 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 kontraktů střední jsou ve skutečnosti Některé identifikační bity se používají k popisu požadavků na interní zprávu. Zde je představen další bod znalostí TON zvolil binární jazyk nazvaný TL-B pro popis způsobu provedení zprávy a implementuje jej nastavením jiného příznaku. bitů Pro interní informace o určitých specifických funkcích jsou dva nejsnáze myšlené scénáře použití: vytvoření nové smlouvy a nasazená volání funkcí smlouvy. Metoda na řádku 51 odpovídá prvně uvedenému, čímž se vytvoří nová položková smlouva nft, kterou specifikují především řádky 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í Binární hodnota je 111 (desítková hodnota je 4+ 2+ 1), z nichž první dva označují, že zpráva bude doprovázena daty StateInit Tato data jsou zdrojovým kódem nového 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, což je podobné tokenId v ERC 721, a aktuální adresu smlouvy vrácenou standardní funkcí moje_adresa, což je adresa_kolekce Pořadí těchto dat je v souladu s deklarací v položce nft.

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 create 2 v Solidity Generování nových adres v TON se skládá ze dvou částí, workchain Identifikační bit je spojen ​​s hodnotou hash stateinit 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 zakódujte vygenerovanou hodnotu 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 konkrétně zdůraznili, že interní zpráva v TON neobsahuje pouze operace, které mohou upravovat data, ale také operace pouze pro čtení. je třeba provést tímto způsobem, takže tato smlouva je taková operace Předně je vhodné poznamenat, že řádek 67 představuje značku funkce zpětného volání žadatele po reakci na požadavek a bude 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 smluv, pojmenované recv_internal a recv_external. První je jednotný vstup pro volání pro všechny interní zprávy a ten druhý je jednotný vstup pro volání pro všechny externí Vývoj zpráv Operátor potřebuje použít metodu podobnou přepínači, aby odpovídal na různé požadavky na základě různých příznakových bitů specifikovaných zprávou v souladu s požadavky. 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 jsou analyzovány bity příznaku operace operace a poté jsou odpovídající požadavky zpracovány 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 vytvořte 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 znát také jejím pojmenováním. Podobně jako u funkce require v Solidity jsou výjimky vyvolány ve Func prostřednictvím standardní funkce throw_unless error code , 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, abyste se střetli s některými novými a zajímavými nápady dapp a společně je rozvinuli.