欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

當(dāng)前位置:主頁 > 區(qū)塊鏈 > 區(qū)塊鏈技術(shù) > 如何在TON Chain上創(chuàng)建NFT

從源碼角度看如何在TON Chain上創(chuàng)建一個NFT

2025-04-28 16:07:59 | 來源: | 作者:佚名
金國深入研究 TON 官方開發(fā)文檔,感覺學(xué)習(xí)起來還是有些門檻,當(dāng)前的文檔內(nèi)容似乎更像是一個內(nèi)部開發(fā)文檔,對新入門的開發(fā)者來說不太友好,因此試著以自己的學(xué)習(xí)軌跡,梳理一系列關(guān)于 TON Chain 項目開發(fā)的文章,希望可以對大家快速入門 TON DApp 開發(fā)有一些幫助,

在 EVM 中開發(fā) NFT 和在 TON Chain 上開發(fā) NFT 有哪些不同

發(fā)行一個 FT 或 NFT 對于 DApp 開發(fā)者來說通常是最基本的需求。因此我也以此作為學(xué)習(xí)入口。首先讓我們來了解以下在 EVM 技術(shù)棧中開發(fā)一個 NFT 和在 TON Chain 中的區(qū)別?;?EVM 的 NFT 通常會選擇繼承 ERC-721 的標準。所謂 NFT,指的是不可分割的加密資產(chǎn)類型,且每個資產(chǎn)具有唯一性,即存在某些專屬的特性。而 ERC-721 就是對這個類型的資產(chǎn)的一種通用的開發(fā)范式。讓我們看一個常見的 ERC721 合約需要實現(xiàn)哪些函數(shù)以及記錄哪些信息。下圖是一個 ERC721 接口??梢钥吹脚c FT 不同,在轉(zhuǎn)賬接口中需要輸入的是待轉(zhuǎn)賬的 tokenId 而非數(shù)量。這個 tokenId 也是 NFT 資產(chǎn)唯一性最基本的體現(xiàn),當(dāng)然為了承載更多的屬性,通常會為每個 tokenId 記錄一個 metadata,這個 metadata 是一個外部鏈接,保存了該 NFT 的其他可擴展數(shù)據(jù),例如一張 PFP 圖片的鏈接,某些屬性名稱等。

P6yhmaC143.png

對于熟悉 Solidity 或者熟悉面向?qū)ο蟮拈_發(fā)者來說,實現(xiàn)這樣一個智能合約是件容易的事,只要定義好合約中需要的數(shù)據(jù)類型,例如一些關(guān)鍵的映射關(guān)系 mapping,并根據(jù)所需功能開發(fā)相應(yīng)的對這些數(shù)據(jù)的修改邏輯,即可實現(xiàn)一個 NFT。

然而在 TON Chain 中這一切變的不太相同,造成不同的核心原因有兩個:

  • 在 TON 中數(shù)據(jù)的存儲是基于 Cell 實現(xiàn)的,而同一個賬戶的 Cell 通過有向無環(huán)圖來實現(xiàn)。這樣就導(dǎo)致需要之久化存儲的數(shù)據(jù)不能無邊界的增長下去,因為一個有向無環(huán)圖來說,數(shù)據(jù)深度決定的查詢成本,當(dāng)深度無限延伸之后,有可能造成查詢成本過高,從而導(dǎo)致合約陷入死鎖問題。

  • 為了追求高并發(fā)性能,TON 舍棄了串行執(zhí)行的架構(gòu),轉(zhuǎn)而采用了一個專為并行而生的開發(fā)范式,Actor 模型,來重構(gòu)執(zhí)行環(huán)境。這就造成了一個影響,智能合約之間只能通過發(fā)送所謂內(nèi)部消息的方式異步調(diào)用,注意無論是狀態(tài)修改類型或只讀類型的調(diào)用都需要遵循這個原則,除此之外,也需要仔細考慮異步調(diào)用若失敗,如何處理數(shù)據(jù)回滾的問題。

    當(dāng)然關(guān)于技術(shù)上其他不同點在上一篇文章中有過詳細的論述,本篇文章希望可以聚焦在智能合約開發(fā)上,所以不展開討論。上述兩條設(shè)計原則讓 TON 中智能合約開發(fā)與 EVM 產(chǎn)生了很大區(qū)別。在開始的論述中,我們知道一個 NFT 合約中需要定義一些映射關(guān)系,也就是 mapping,來保存 NFT 相關(guān)的數(shù)據(jù)。其中最重要的就是 owners,這個 mapping 存儲了某個 tokenID 對應(yīng)的 NFT 的所有者地址的映射關(guān)系,決定了 NFT 的所有權(quán),轉(zhuǎn)賬就是對該所有權(quán)的修改。由于理論上這是一個可以無邊界的數(shù)據(jù)結(jié)構(gòu),需要盡量避免。因此官方推薦以是否存在無邊界數(shù)據(jù)結(jié)構(gòu)作為分片的標準。即當(dāng)有類似的數(shù)據(jù)存儲需求時,通過主從合約的范式來替代,通過創(chuàng)建子合約的方式來管理每個 key 對應(yīng)的數(shù)據(jù)。并通過主合約管理全局參數(shù),或幫助處理子合約之間的內(nèi)部信息交互。

    這也就意味著在 TON 中的 NFT 也需要采用類似的架構(gòu)來設(shè)計,每個 NFT 都是一個獨立的子合約,保存了諸如所有者地址,metadata 等專屬數(shù)據(jù),并通過一個主合約來管理全局數(shù)據(jù),例如 NFT name,symbol,總供應(yīng)量等。

    在明確了架構(gòu)后,接下來就需要解決核心功能的需求了,由于采用了這個主從合約的方式,因此就需要明確哪些功能由主合約承載,哪些功能由子合約承載,并且兩者之間通過什么內(nèi)部信息溝通,同時當(dāng)出現(xiàn)執(zhí)行錯誤時,如何回滾之前的數(shù)據(jù)。通常情況下,在開發(fā)復(fù)雜的大型項目之前,通過一個類圖并明確彼此之間的信息流,并仔細思考內(nèi)部調(diào)用失敗后的回滾邏輯是必要的,當(dāng)然上述 NFT 開發(fā)雖然簡單,但也可以做類似驗證。

    9Ztfcz93Zz.png

    從源碼學(xué)習(xí)開發(fā) TON 智能合約

    TON 選擇了設(shè)計一種類 C 語言的、靜態(tài)類型語言,名為 Func 來作為智能合約開發(fā)語言,那么接下來就讓我們從源碼來學(xué)習(xí)如何開發(fā) TON 智能合約,我選擇了 TON 官方文檔中的 NFT 示例來進行介紹,感興趣的小伙伴可以自行去查閱。在這個 case 中實現(xiàn)了一個簡單的 TON NFT 例。讓我們看下合約結(jié)構(gòu),共分為兩個功能合約以及三個必要的庫。

    kDAvnWDXv9.png

    這兩個主要的功能合約即按照上述的原則進行設(shè)計,首先讓我們來看下主合約 nft-collection 的代碼:

    J5p9hzzlMr.png

    這引入了第一個知識點,如何在 TON 智能合約中持久化存儲數(shù)據(jù),我們知道在 Solidity 中數(shù)據(jù)的持久化存儲是由 EVM 根據(jù)參數(shù)的類型自動處理的,通常情況下,智能合約的狀態(tài)變量將在執(zhí)行結(jié)束后根據(jù)最新值自動被持久化存儲,開發(fā)者并不需要考慮這個過程。但在 Func 中情況并不如此,開發(fā)者需要自己來實現(xiàn)相應(yīng)的處理邏輯,這個情況有點類似于 C 和 C++ 需要考慮 GC 的過程,但其他新的開發(fā)語言通常將這部分邏輯自動化處理。我們來看下代碼,首先引入一些需要的庫,然后看到第一個函數(shù) load_data 用于讀取被持久化存儲的數(shù)據(jù),其邏輯為首先通過 get_data 返回持久化合約存儲 cell,注意這是由標準庫 stdlib.fc 實現(xiàn)的,通常情況下可以將其中的一些函數(shù)視為系統(tǒng)函數(shù)來使用。

    該函數(shù)的返回值類型為 cell,這是 TVM 中的 cell 類型。在之前的介紹中,我們已經(jīng)知道 TON 區(qū)塊鏈中的所有持久數(shù)據(jù)都存儲在 cell 樹中。每個 cell 最多有 1023 位任意數(shù)據(jù)和最多四個對其他 cell 的引用。cell 在基于堆棧的 TVM 中用作內(nèi)存。cell 中保存的是緊編碼后的數(shù)據(jù),要想獲取其中具體的明文數(shù)據(jù),需要將 cell 轉(zhuǎn)換為被稱為 slice 的類型。cell 可以通過 begin_parse 函數(shù)轉(zhuǎn)換成為 slice 類型,然后可以通過從 slice 加載數(shù)據(jù)位和對其他 cell 的引用來獲得 cell 中的數(shù)據(jù)。注意 15 行代碼中的這種調(diào)用方法是一個 func 中的語法糖,可以直接調(diào)用第一個函數(shù)的返回值的第二個函數(shù)。并在最后按照數(shù)據(jù)持久化順序依次加載相應(yīng)的數(shù)據(jù)。注意這個過程和 solidity 不同,并不是根據(jù) hashmap 調(diào)用,所以這個調(diào)用順序不能亂。

    在 save_data 函數(shù)中,邏輯與之類似,只不過這是一個反向的過程,這就引入了下一個知識點,一個新的類型 builder,這是 cell 構(gòu)建器的類型。數(shù)據(jù)位和對其他 cell 的引用可以存儲在構(gòu)建器中,然后構(gòu)建器可以最終化為新 cell。首先通過標準函數(shù) begin_cell 創(chuàng)建一個 builder,并依次通過 store 相關(guān)函數(shù)存儲相關(guān)函數(shù),注意上文中調(diào)用順序與此處存儲順序需要保持一致。最后通過 end_cell 完成新 cell 構(gòu)建,這時該 cell 被管理在內(nèi)存中,最后通過最外層的 set_data,就可以完成對該 cell 的持久化存儲。

    p1926pA9lg.png

    接下來讓我們來看下業(yè)務(wù)相關(guān)函數(shù),首先需要先介紹下一個知識點,如何通過合約創(chuàng)建一個新的合約,這在剛剛介紹的主從架構(gòu)中將被經(jīng)常用到。我們知道在 TON 中,智能合約之間的調(diào)用是通過發(fā)送內(nèi)部消息的方式來實現(xiàn)的。這是通過一個名為 send_raw_message 來實現(xiàn)的,注意第一個參數(shù)是 message 編碼后的 cell,第二個參數(shù)是標識位,用于表明該交易的執(zhí)行方式的區(qū)別,在 TON 中設(shè)置了不同的內(nèi)部消息發(fā)送的執(zhí)行方式,目前有 3 種消息 Modes 和 3 種消息 Flags??梢詫我?Mode 與多個(也許沒有)標志組合以獲得所需的 mode。組合只是意味著將它們值的和填入即可。下面給出了 Modes 和 Flags 的描述表格:

    z76GSc3O4S.png

    那么讓我們來看第一個主要函數(shù),deploy_nft_item,顧名思義,這是一個用于創(chuàng)建或者說鑄造新 NFT 實例的函數(shù),經(jīng)過一番操作編碼一個 msg 后,通過 send_raw_message 發(fā)送該內(nèi)部合約,并選擇了 flag 1 的發(fā)送標識位,僅將編碼中指定的 fee 作為本次執(zhí)行的 gas fee。經(jīng)過上文的介紹我們很容易意識到,這個編碼規(guī)則應(yīng)該是對應(yīng)創(chuàng)建一個新的智能合約的方式。那讓我們來看看具體是怎么實現(xiàn)的。

    讓我們直接看 51 行,上面兩個函數(shù)是用于生成 message 所需信息的輔助函數(shù),因此我們后面再來看,這是一個用于創(chuàng)建智能合約的內(nèi)部消息的編碼過程,中間的一些數(shù)字其實也是一些標識位,用于說明該內(nèi)部消息的需求,這里要引入下一個知識點,TON 選擇了一種名為 TL-B 的二進制語言來描述消息的執(zhí)行方式,并且根據(jù)設(shè)置不同的標記位來實現(xiàn)某些特定功能的內(nèi)部消息,最容易想到的兩個使用場景,新合約創(chuàng)建和已部署合約函數(shù)調(diào)用。而 51 行的這種方式即對應(yīng)了前者,創(chuàng)建一個新的 nft item 合約,而這主要是通過 55,56,57 三行指定的。首先 55 行這一大串?dāng)?shù)字是一系列標識位,注意 store_uint 的第一個入?yún)⑹菙?shù)值,第二個是位長,其中決定了該內(nèi)部消息是合約創(chuàng)建的是后三個標記位,以及相應(yīng)二進制值位為 111(十進制即為 4+2+1),其中前兩個表示該消息將附帶 StateInit 數(shù)據(jù),這個數(shù)據(jù)即為新合約的源碼,以及初始化所需的數(shù)據(jù)。而后一個標記位表示內(nèi)部消息附載,即希望執(zhí)行相關(guān)邏輯以及需要的參數(shù)。因此你會看到在第 66 行代碼并沒有設(shè)置該三位數(shù)據(jù),則表明的是一次對已部署合約的函數(shù)調(diào)用。具體的編碼規(guī)則在這里查看。

    那么 StateInit 的編碼規(guī)則即對應(yīng)了 49 行代碼,通過 calculate_nft_item_state_init 計算,注意 stateinit 數(shù)據(jù)的編碼也遵循了一種既定的 TL-B 編碼規(guī)則,除了一些標記位之外,主要涉及到兩部分新合約 code 和以及初始化 data。data 的編碼順序需要與新合約指定的持久化 cell 的存儲順序保持一致。在 36 行可以看到,初始化數(shù)據(jù)有 item_index,即類似與 ERC721 中的 tokenId,以及由標準函數(shù) my_address 返回的當(dāng)前合約地址,即為 collection_address,這個數(shù)據(jù)的順序與 nft-item 中的聲明保持一致。

    接下來一個知識點就是在 TON 中,所有未生成的智能合約而可以預(yù)先計算其生成后的地址,這點與 Solidity 中的 create2 函數(shù)類似,在 TON 中新地址的生成由兩部分組成,workchain 標識位與 stateinit 的哈希值拼接而成,前者在之前的介紹中我們已經(jīng)知道是為了相應(yīng) TON 無限分片架構(gòu)而需要被指定的,當(dāng)前為統(tǒng)一值。由標準函數(shù) workchain 獲得。后者由標準函數(shù) cell_hash 獲得。因此回到該例子,calculate_nft_item_address 即為預(yù)先計算新合約地址的函數(shù)。并將生成值在第 53 行編碼到 message 中,作為該內(nèi)部消息的接收地址。而 nft_content 則對應(yīng)了對被創(chuàng)建合約的初始化調(diào)用,具體的實現(xiàn)在下一篇文章中介紹。

    至于 send_royalty_params,則需要是對某只讀請求的內(nèi)部消息的相應(yīng),在之前的介紹中,我們特意強調(diào)了在 TON 中內(nèi)部消息不光包含可能會修改數(shù)據(jù)的操作,只讀操作也需要通過這種方式實現(xiàn),因此該合約即為此類操作,首先值得注意的是 67 行表示響應(yīng)該請求后對請求者回調(diào)函數(shù)的標記,記下來即為返回的數(shù)據(jù),分別是請求的 item index,以及相應(yīng)的 royalty 數(shù)據(jù)。 

    接下來讓我們引入下一個知識點,TON 中智能合約只有兩個統(tǒng)一的入口,名為 recv_internal 和 recv_external,其中前者為所有內(nèi)部消息的統(tǒng)一調(diào)用入口,后者為所有外部消息的統(tǒng)一調(diào)用入口,開發(fā)者需要在函數(shù)內(nèi)部根據(jù)需求,采用類似 switch 的方式根據(jù) message 指定的不同標記位來響應(yīng)不同的請求,這里的標記位即為上述 67 行的回調(diào)函數(shù)標記。回到該例子,首先對 message 進行空位檢查,通過后分別解析 message 中的信息,首先在 83 行解析獲得 sender_address,該參數(shù)將用于后續(xù)的權(quán)限檢查,注意這里的~操作符,屬于另一個語法糖。這里先不展開將。接下來解析 op 操作標記位,而后根據(jù)不同的標記位,分別處理相應(yīng)請求。其中即根據(jù)某些邏輯分別調(diào)用了上述的函數(shù)。例如響應(yīng)對 royalty 參數(shù)的請求,或鑄造新的 nft,并自增全局 index。 

    接下來一個知識點對應(yīng)了 108 行,想必大家通過命名也可以知道該函數(shù)的處理邏輯,與 Solidity 中的 require 函數(shù)類似,F(xiàn)unc 中通過標準函數(shù) throw_unless 來拋出異常,第一個入?yún)殄e誤碼,第二個是檢查位布爾值,若位 false 則拋出異常,并附帶該錯誤碼。而在這行中通過 equal_slices 來判斷上面解析到的 sender_address 是否等于該合約持久化存儲的 owner_address,做權(quán)限判斷。

    Xg1dKPk83l.png

    最后為了使代碼結(jié)構(gòu)更清晰,開始閑了一系列幫助獲取持久化信息的輔助函數(shù),在這里就不展開介紹了,開發(fā)者可以參考這種結(jié)構(gòu)來開發(fā)自己的智能合約。

    3DukH2og9o.png

    TON 生態(tài)的 DApp 開發(fā)實在是件有趣的事情,與 EVM 的開發(fā)范式有很大差異,因此我會通過一系列文章來介紹如何在 TON Chain 中開發(fā) DApp。

    聲明:文章內(nèi)容不代表本站觀點及立場,不構(gòu)成本平臺任何投資建議。本文內(nèi)容僅供參考,風(fēng)險自擔(dān)!
    Tag:NFT   Chain   ton  

    你可能感興趣的文章

    幣圈快訊

    • 前Galaxy高管發(fā)文質(zhì)疑以太坊基金會新組織架構(gòu)混亂

      2025-06-12 13:53
      ChainCatcher消息,前GalaxyDigital研究副總裁ChristineKim于X平臺發(fā)文指出,新的以太坊基金會組織架構(gòu)令人困惑。她提到,TimBeiko、BarnabéMonnot和AlexStokes身兼多職,既要領(lǐng)導(dǎo)基金會所有研發(fā)團隊,又要管理自身團隊,且需在未來12個月內(nèi)負責(zé)L1、L2擴容及改善用戶體驗(UX)。 此外,Christine對架構(gòu)圖細節(jié)存疑,包括加粗名字是否為團隊負責(zé)人、高亮部分用途,以及Tim是否負責(zé)協(xié)議協(xié)調(diào)并監(jiān)督多個項目。 同時,她對顏色分組邏輯表示不解,如為何將共識機制與賬戶抽象分一組,卻未將無狀態(tài)共識等納入;為何Testing與pandaops分一組,而Security卻未被分組。
    • OpenSea宣布將于6月16日完全關(guān)閉OS1版本,并將在OS2更新中關(guān)閉\"Deals\"等功能

      2025-06-12 13:47
      金色財經(jīng)報道,據(jù)Blockworks報道,OpenSea宣布將于6月16日完全關(guān)閉OS1版本,新版OS2將不會保留包括Deals(自定義交易)、英式拍賣、測試網(wǎng)支持和購物車等多項功能。OpenSea表示,Deals和英式拍賣功能因使用率低而被砍掉。此決定在社區(qū)引發(fā)爭議,多位用戶擔(dān)憂取消Deals功能將增加交易風(fēng)險,而OpenSea首席營銷官AdamHollander解釋稱,該功能與強制版稅的ERC721-C合約不兼容,導(dǎo)致產(chǎn)品體驗不一致。
    • 分析師:通脹走弱與資金流入共振,比特幣年底或漲至20萬美元

      2025-06-12 13:47
      ChainCatcher消息,美國5月CPI同比上漲2.4%,低于市場預(yù)期(2.5%),引發(fā)市場對年內(nèi)降息的更高預(yù)期。有觀點認為,通脹放緩幅度超預(yù)期或成為比特幣加速上漲的催化劑。 21Shares的加密研究策略師MattMena預(yù)計,若BTC突破10.5萬至11萬美元區(qū)間,預(yù)計短期將升至12萬美元,下半年或達13.8萬美元,年底有望沖擊20萬美元。其指出,通脹持續(xù)走弱強化了貨幣寬松基礎(chǔ),疊加BTC儲備公司數(shù)量上升、美國多州推出BTC儲備計劃,將共同推動資金凈流入,支撐比特幣價格中長期走勢。
    • InfinexsKAITO空投已開放申領(lǐng)

      2025-06-12 13:43
      6月12日消息,據(jù)官方消息,跨鏈聚合DeFi平臺InfinexsKAITO空投已開放申領(lǐng)。符合條件的sKAITO或YT-sKAITO持有者可從Infinex賬戶中領(lǐng)取1億枚μPatrons。快照拍攝日期為6月4日。
    • TrumpMeme官方已向參加晚宴用戶發(fā)放紀念NFT

      2025-06-12 13:22
      6月12日消息,TrumpMeme官方宣布已向參加TRUMP晚宴用戶發(fā)放紀念NFT,用戶可在參與活動的Solana錢包上查看。另據(jù)鏈上信息顯示,該系列NFT由Metaplex提供技術(shù)支持,數(shù)據(jù)則存儲在鏈上數(shù)據(jù)開發(fā)商Irys平臺。
    • 查看更多