TON 项目开发教程(一):源码角度看如何在 TON Chain 上创建一个NFT
作者:@web3mario(https://x.com/web3_mario)
2026虚拟币交易平台推荐:
- 欧易(OKX)交易平台(>>>进入官网<<<)(下载OKX的Android安装包)
- 币安(Binance)交易平台(>>>进入官网<<<)(下载币安Android安装包)
摘要:承接上一篇关于TON技术介绍的文章,这段时间深入研究了一下TON最新开发文档,感觉学习起来还是有些门槛,当前的文档内容似乎更像是一个内部开发文档,对新入门的开发者来说不太友好,因此试着以自己的学习轨迹,梳理一系列关于TON Chain项目开发的文章,希望可以对大家快速入门TON DApp开发有一些帮助。行文有误也欢迎大家指正,一起学习。
在EVM中开发NFT和在TON Chain上开发NFT有哪些不同发行一个FT或NFT对于DApp开发者来说通常是最基本的需求。因此我也以此作为学习入口。首先让我们来了解以下在EVM技术栈中开发一个NFT和在TON Chain中的区别。基于EVM的NFT通常会选择继承ERC-721的标准。所谓NFT,指的是不可分割的加密资产类型,且每个资产具有唯一性,即存在某些专属的特性。而ERC-721就是对这个类型的资产的一种通用的开发范式。让我们看一个常见的ERC721合约需要实现哪些函数以及记录哪些信息。下图是一个ERC721接口。可以看到与FT不同,在转账接口中需要输入的是待转账的tokenId而非数量。这个tokenId也是NFT资产唯一性最基本的体现,当然为了承载更多的属性,通常会为每个tokenId记录一个metadata,这个metadata是一个外部链接,保存了该NFT的其他可扩展数据,例如一张PFP图片的链接,某些属性名称等。
对于熟悉Solidity或者熟悉面向对象的开发者来说,实现这样一个智能合约是件容易的事,只要定义好合约中需要的数据类型,例如一些关键的映射关系mapping,并根据所需功能开发相应的对这些数据的修改逻辑,即可实现一个NFT。
然而在TON Chain中这一切变的不太相同,造成不同的核心原因有两个:
在TON中数据的存储是基于Cell实现的,而同一个账户的Cell通过有向无环图来实现。这样就导致需要之久化存储的数据不能无边界的增长下去,因为一个有向无环图来说,数据深度决定的查询成本,当深度无限延伸之后,有可能造成查询成本过高,从而导致合约陷入死锁问题。为了追求高并发性能,TON舍弃了串行执行的架构,转而采用了一个专为并行而生的开发范式,Actor模型,来重构执行环境。这就造成了一个影响,智能合约之间只能通过发送所谓内部消息的方式异步调用,注意无论是状态修改类型或只读类型的调用都需要遵循这个原则,除此之外,也需要仔细考虑异步调用若失败,如何处理数据回滚的问题。当然关于技术上其他不同点在上一篇文章中有过详细的论述,本篇文章希望可以聚焦在智能合约开发上,所以不展开讨论。上述两条设计原则让TON中智能合约开发与EVM产生了很大区别。在开始的论述中,我们知道一个NFT合约中需要定义一些映射关系,也就是mapping,来保存NFT相关的数据。其中最重要的就是owners,这个mapping存储了某个tokenID对应的NFT的所有者地址的映射关系,决定了NFT的所有权,转账就是对该所有权的修改。由于理论上这是一个可以无边界的数据结构,需要尽量避免。因此最新推荐以是否存在无边界数据结构作为分片的标准。即当有类似的数据存储需求时,通过主从合约的范式来替代,通过创建子合约的方式来管理每个key对应的数据。并通过主合约管理全局参数,或帮助处理子合约之间的内部信息交互。
这也就意味着在TON中的NFT也需要采用类似的架构来设计,每个NFT都是一个独立的子合约,保存了诸如所有者地址,metadata等专属数据,并通过一个主合约来管理全局数据,例如NFT name,symbol,总供应量等。
在明确了架构后,接下来就需要解决核心功能的需求了,由于采用了这个主从合约的方式,因此就需要明确哪些功能由主合约承载,哪些功能由子合约承载,并且两者之间通过什么内部信息沟通,同时当出现执行错误时,如何回滚之前的数据。通常情况下,在开发复杂的大型项目之前,通过一个类图并明确彼此之间的信息流,并仔细思考内部调用失败后的回滚逻辑是必要的,当然上述NFT开发虽然简单,但也可以做类似验证。
从源码学习开发TON智能合约TON选择了设计一种类 C 语言的、静态类型语言,名为Func来作为智能合约开发语言,那么接下来就让我们从源码来学习如何开发TON智能合约,我选择了TON最新文档中的NFT示例来进行介绍,感兴趣的小伙伴可以自行去查阅。在这个case中实现了一个简单的TON NFT例。让我们看下合约结构,共分为两个功能合约以及三个必要的库。
这两个主要的功能合约即按照上述的原则进行设计,首先让我们来看下主合约nft-collection的代码:
这引入了第一个知识点,如何在TON智能合约中持久化存储数据,我们知道在Solidity中数据的持久化存储是由EVM根据参数的类型自动处理的,通常情况下,智能合约的状态变量将在执行结束后根据最新值自动被持久化存储,开发者并不需要考虑这个过程。但在Func中情况并不如此,开发者需要自己来实现相应的处理逻辑,这个情况有点类似于C和C++需要考虑GC的过程,但其他新的开发语言通常将这部分逻辑自动化处理。我们来看下代码,首先引入一些需要的库,然后看到第一个函数load_data用于读取被持久化存储的数据,其逻辑为首先通过get_data返回持久化合约存储cell,注意这是由标准库stdlib.fc实现的,通常情况下可以将其中的一些函数视为系统函数来使用。
该函数的返回值类型为cell,这是 TVM中的cell类型。在之前的介绍中,我们已经知道TON 区块链中的所有持久数据都存储在cell树中。每个cell最多有 1023 位任意数据和最多四个对其他cell的引用。cell在基于堆栈的 TVM 中用作内存。cell中保存的是紧编码后的数据,要想获取其中具体的明文数据,需要将cell转换为被称为slice的类型。cell可以通过begin_parse函数转换成为slice类型,然后可以通过从slice加载数据位和对其他cell的引用来获得cell中的数据。注意15行代码中的这种调用方法是一个func中的语法糖,可以直接调用第一个函数的返回值的第二个函数。并在最后按照数据持久化顺序依次加载相应的数据。注意这个过程和solidity不同,并不是根据hashmap调用,所以这个调用顺序不能乱。
在save_data函数中,逻辑与之类似,只不过这是一个反向的过程,这就引入了下一个知识点,一个新的类型builder,这是cell构建器的类型。数据位和对其他cell的引用可以存储在构建器中,然后构建器可以最终化为新cell。首先通过标准函数begin_cell创建一个builder,并依次通过store相关函数存储相关函数,注意上文中调用顺序与此处存储顺序需要保持一致。最后通过end_cell完成新cell构建,这时该cell被管理在内存中,最后通过最外层的set_data,就可以完成对该cell的持久化存储。
接下来让我们来看下业务相关函数,首先需要先介绍下一个知识点,如何通过合约创建一个新的合约,这在刚刚介绍的主从架构中将被经常用到。我们知道在TON中,智能合约之间的调用是通过发送内部消息的方式来实现的。这是通过一个名为send_raw_message来实现的,注意第一个参数是message编码后的cell,第二个参数是标识位,用于表明该交易的执行方式的区别,在TON中设置了不同的内部消息发送的执行方式,目前有3种消息Modes和3种消息Flags。可以将单一Mode与多个(也许没有)标志组合以获得所需的mode。组合只是意味着将它们值的和填入即可。下面给出了Modes和Flags的描述表格:
那么让我们来看第一个主要函数,deploy_nft_item,顾名思义,这是一个用于创建或者说铸造新NFT实例的函数,经过一番操作编码一个msg后,通过send_raw_message发送该内部合约,并选择了flag 1的发送标识位,仅将编码中指定的fee作为本次执行的gas fee。经过上文的介绍我们很容易意识到,这个编码规则应该是对应创建一个新的智能合约的方式。那让我们来看看具体是怎么实现的。
让我们直接看51行,上面两个函数是用于生成message所需信息的辅助函数,因此我们后面再来看,这是一个用于创建智能合约的内部消息的编码过程,中间的一些数字其实也是一些标识位,用于说明该内部消息的需求,这里要引入下一个知识点,TON选择了一种名为TL-B 的二进制语言来描述消息的执行方式,并且根据设置不同的标记位来实现某些特定功能的内部消息,最容易想到的两个使用场景,新合约创建和已部署合约函数调用。而51行的这种方式即对应了前者,创建一个新的nft item合约,而这主要是通过55,56,57三行指定的。首先55行这一大串数字是一系列标识位,注意store_uint的第一个入参是数值,第二个是位长,其中决定了该内部消息是合约创建的是后三个标记位,以及相应二进制值位为111(十进制即为4+2+1),其中前两个表示该消息将附带StateInit数据,这个数据即为新合约的源码,以及初始化所需的数据。而后一个标记位表示内部消息附载,即希望执行相关逻辑以及需要的参数。因此你会看到在第66行代码并没有设置该三位数据,则表明的是一次对已部署合约的函数调用。具体的编码规则在这里查看。
那么StateInit的编码规则即对应了49行代码,通过calculate_nft_item_state_init计算,注意stateinit数据的编码也遵循了一种既定的TL-B编码规则,除了一些标记位之外,主要涉及到两部分新合约code和以及初始化data。data的编码顺序需要与新合约指定的持久化cell的存储顺序保持一致。在36行可以看到,初始化数据有item_index,即类似与ERC721中的tokenId,以及由标准函数my_address返回的当前合约地址,即为collection_address,这个数据的顺序与nft-item中的声明保持一致。
接下来一个知识点就是在TON中,所有未生成的智能合约而可以预先计算其生成后的地址,这点与Solidity中的create2函数类似,在TON中新地址的生成由两部分组成,workchain标识位与stateinit的哈希值拼接而成,前者在之前的介绍中我们已经知道是为了相应TON无限分片架构而需要被指定的,当前为统一值。由标准函数workchain获得。后者由标准函数cell_hash获得。因此回到该例子,calculate_nft_item_address即为预先计算新合约地址的函数。并将生成值在第53行编码到message中,作为该内部消息的接收地址。而nft_content则对应了对被创建合约的初始化调用,具体的实现在下一篇文章中介绍。
至于send_royalty_params,则需要是对某只读请求的内部消息的相应,在之前的介绍中,我们特意强调了在TON中内部消息不光包含可能会修改数据的操作,只读操作也需要通过这种方式实现,因此该合约即为此类操作,首先值得注意的是67行表示响应该请求后对请求者回调函数的标记,记下来即为返回的数据,分别是请求的item index,以及相应的royalty数据。
接下来让我们引入下一个知识点,TON中智能合约只有两个统一的入口,名为recv_internal和recv_external,其中前者为所有内部消息的统一调用入口,后者为所有外部消息的统一调用入口,开发者需要在函数内部根据需求,采用类似switch的方式根据message指定的不同标记位来响应不同的请求,这里的标记位即为上述67行的回调函数标记。回到该例子,首先对message进行空位检查,通过后分别解析message中的信息,首先在83行解析获得sender_address,该参数将用于后续的权限检查,注意这里的~操作符,属于另一个语法糖。这里先不展开将。接下来解析op操作标记位,而后根据不同的标记位,分别处理相应请求。其中即根据某些逻辑分别调用了上述的函数。例如响应对royalty参数的请求,或铸造新的nft,并自增全局index。
接下来一个知识点对应了108行,想必大家通过命名也可以知道该函数的处理逻辑,与Solidity中的require函数类似,Func中通过标准函数throw_unless来抛出异常,第一个入参为错误码,第二个是检查位布尔值,若位false则抛出异常,并附带该错误码。而在这行中通过equal_slices来判断上面解析到的sender_address是否等于该合约持久化存储的owner_address,做权限判断。
最后为了使代码结构更清晰,开始闲了一系列帮助获取持久化信息的辅助函数,在这里就不展开介绍了,开发者可以参考这种结构来开发自己的智能合约。
TON生态的DApp开发实在是件有趣的事情,与EVM的开发范式有很大差异,因此我会通过一系列文章来介绍如何在TON Chain中开发DApp。与大家共同学习,把握这波机会。也欢迎大家在twitter上与我互动,碰撞一些新的有趣的dapp idea,一起开发。
相关攻略
MultiBank Group的MBG代币生成事件:连接传统金融与区块链的关键一步 市场准备好了吗?MultiBank Group正通过其原生代币MBG的代币生成事件(TGE),实实在在地搅动着市场格局。这绝非又一个空洞的加密叙事,而是一家在传统金融领域深耕多年的巨头,主动拥抱去中心化趋势的战略性落
波场币(TRX)实时价格查询App:官方下载与使用全指南 波场币(TRX)是波场协议的原生代币,而这个协议本身,志在构建一个去中心化的互联网基础设施。简单来说,它的目标是打造一个高效、低成本的数字内容娱乐生态系统,让创作者能真正掌握自己数据的所有权和分发权。 说到大家最关心的价格,根据最新的市场数据
币安(Binance):全球领先的数字资产交易平台 在当今的数字资产领域,币安(Binance)无疑是绕不开的名字。作为全球顶级的区块链资产交易平台,它为用户提供了安全、便捷的主流虚拟数字货币交易服务。对于初次接触的用户而言,如何顺利下载并安装官方App是第一步。本文将手把手带你完成整个过程,并提供
Web3的核心:从“租客”到“房东”的互联网权力转移 想彻底理解Web3,其实不必一头扎进那些晦涩的技术术语里。把它看作互联网的一次根本性“代际升级”,思路就清晰多了。而要看清这“下一代”的模样,最好的方法就是回头看看它的“前两代”是什么样子。 简单来说,Web3的核心目标,是让用户真正拥有自己的数
欧洲为乌克兰长期战争做准备,却又没有结束战争的战略,这使得停火的可能性越来越低 目前,俄乌两国在2026年6月30日之前实现停火的市场价格为7 5%。是的,比一天前的8%有所下降。这个数字本身,就透露出市场的普遍预期。 市场反应 距离2026年6月停火协议市场的最终结算日,还有67天。交易员们用真金
热门专题
热门推荐
微软调整XGP战略:降价与《使命召唤》延期入库的背后 最近游戏圈有个大消息:微软宣布下调Xbox Game Pass Ultimate和PC Game Pass的月度订阅价格。具体来看,Ultimate档位从每月29 99美元降到了22 99美元,PC Game Pass则从16 49美元降至13
2026年,Xbox新掌门的第一把火:Game Pass要变“自助餐”了 2026年2月,阿莎·夏尔马接棒菲尔·斯宾塞,成为Xbox的新任CEO。这位新官上任,动作可谓雷厉风行。就在昨天,她点燃了第一把火:Xbox Game Pass Ultimate的月费,从29 99美元直接降到了22 99美元
当明星演员想开游戏工作室:资深同行为何直言“别这么做”? 最近,游戏圈里发生了一场有趣的隔空对话。为《最后生还者》《死亡搁浅》等大作献声的知名演员特洛伊·贝克,在采访中透露了一个雄心勃勃的计划:他想创立自己的游戏工作室,去讲述“自己的故事”。他甚至提到,自己的灵感来源之一,正是曾为《刺客信条:起源》
Steam新款手柄评测视频意外流出,定价信息同步曝光 游戏硬件圈最近有个不大不小的“意外”。根据海外多个科技消息源的报道,Valve即将推出的新款Steam Controller手柄,其评测视频竟然提前在网上泄露了。更关键的是,视频里还直接公布了这款产品的售价:99美元。 事情是这样的:一个名为“T
此前,外网消息源透露,目前PlayStation在PS4和PS5的数字版游戏中加入了DRM验证(正版在线验证)机制。 前情提要>> 简单来说,这个新机制的效果是这样的:从今往后,如果你通过数字商店购买新游戏,那么主机就必须定期连接到PSN网络进行正版验证。具体规则是,如果主机连续超过30天处于离线状













