0

0

TON智能合约的安全隐患与优化建议

DDD

DDD

发布时间:2024-09-23 21:00:23

|

975人浏览过

|

来源于脚本之家

转载

区块链技术快速发展的今天,ton (the open network) 作为一款高效且灵活的区块链平台,正受到越来越多开发者的关注。ton 的独特架构和特性为去中心化应用的开发提供了强大的工具和丰富的可能性。

然而,随着功能和复杂性的增加,智能合约的安全性也变得越来越重要。FunC 作为 TON 上的智能合约编程语言,以其灵活性和高效性著称,但同时也带来了许多潜在的风险和挑战。编写安全可靠的智能合约,需要开发者深刻理解 FunC 语言的特性以及可能存在的风险。

本文将详细分析在 TON 区块链上的一些与智能合约有关的特性,以及TON上智能合约容易被忽略的漏洞点。

TON智能合约的安全隐患与优化建议

Ton 异步特性与账户机制解析

智能合约异步调用

网络分片与异步通信

TON 区块链在设计上分为三种链:主链(Masterchain),工作链(Workingchains)和分片链(Shardchains)。

主链是整个网络的核心,负责存储全网的元数据和共识机制。它记录所有工作链和分片链的状态,并确保全网的一致性和安全性。工作链是独立的区块链,最多有 2^32条,负责处理特定类型的交易和智能合约。每个工作链可以有自己的规则和特性,以满足不同的应用需求。分片链是工作链的子链,用于进一步分割工作链的负载,提升处理能力和扩展性。每个工作链最多拆分为 2^60 个 shard chain,分片链独立处理部分交易,从而实现高效的并行处理。

理论上每一个账户都可以独占一个 shard chain,每一个账户独立维护自己的 COIN/TOKEN 余额,每一个账户间的交易都可以完全并行。账户与账户间通过异步消息进行传递,消息在 shard chain 间传递的路径为 log_16(N) - 1,其中 N 为 shard chain 的数量。

TON智能合约的安全隐患与优化建议图源:https://frontierlabzh.medium.com/ton-web3世界的weixin-e1d3ae3b3574

在Ton中,智能合约通过发送和接收消息进行交互。这些消息可以是内部消息(一般来说是智能合约互相交互所发送的消息)或外部消息(由外部来源发送的消息)。消息的传递过程不需要等待目标合约的立即响应,发送方可以继续执行其余的逻辑代码。这种异步消息传递机制相较于以太坊的同步调用,提供了更高的灵活性和扩展性,减少了因等待响应导致的性能瓶颈,同时也带来了处理并发和竞争条件的挑战。

消息格式与结构

在Ton中,消息通常包含发件人、收件人、金额、消息体等信息。消息体可以是函数调用、数据传输或其他自定义内容。Ton使用的消息格式可以灵活定义和扩展,使得不同合约之间能够高效传递各种类型的信息。

TON智能合约的安全隐患与优化建议

消息队列与状态处理

每个合约都维护一个消息队列,存储尚未处理的消息。合约在执行过程中,会根据队列中的消息逐个处理。由于消息处理是异步的,合约的状态在收到消息之前不会立即更新。

异步消息传递的优势

•高效的分片机制:Ton的异步机制与其分片设计高度契合。每个分片独立处理合约的消息和状态变化,避免了跨分片同步通信带来的延迟问题。这种设计提升了整个网络的吞吐量和可扩展性。

•降低资源消耗:由于异步消息不要求即时响应,Ton的合约执行可以分散在多个区块内完成,避免了单个区块内资源的过度消耗。这使得Ton能够支持更为复杂和资源密集型的智能合约。

•容错性与可靠性:异步消息的传递机制使得系统更具容错性。例如,如果某个合约由于资源限制或其他原因无法及时响应消息,发送方仍然可以继续处理其他逻辑,系统不会因为单个合约的延迟而停滞。

异步合约设计的挑战

•状态一致性问题:由于消息传递是异步的,合约的状态在不同时刻可能会接收到不同的消息,这需要开发者特别注意状态一致性问题。在设计合约时,必须考虑到不同消息顺序可能带来的状态变化,确保系统在任何情况下都能保持一致性。

•竞争条件与防护:异步消息处理带来了潜在的竞争条件问题,多个消息可能同时尝试修改合约状态。开发者需要引入适当的锁机制或使用事务性操作来防止状态冲突。

•安全性考量:异步合约在处理跨合约通信时,容易受到中间人攻击或重放攻击。因此,在设计异步合约时,必须考虑到这些潜在的安全风险,并采取措施防止它们发生,如使用时间戳、随机数或多重签名等手段。

账本模型

Ton(The Open Network)在设计其区块链基础设施时,采用了一种独特的账户抽象和账本模型。这个模型的灵活性体现在它如何处理账户的状态、消息传递以及合约的执行。

账户抽象

Ton的账户模型采用了一种基于合约的抽象,每个账户都可以视为一个合约,这与以太坊的账户抽象模型有一些相似之处,但更加灵活和通用。在Ton中,账户不仅仅是持有资产的容器,它们还包含了合约代码和状态数据。每个账户都由其代码(Code)、数据(Data)和消息处理(Message Handling)逻辑组成。

账户结构:每个Ton账户都有一个唯一的地址,该地址是由账户代码的哈希值、部署时的初始数据以及一些其他参数组合而成的。这意味着同样的代码和初始数据部署在不同的环境下(例如,不同的区块链或分片)可能会生成不同的地址。

灵活性:由于每个账户都可以运行自己的合约代码,因此Ton的账户可以实现非常复杂的逻辑。账户不仅仅是简单的余额持有者,还可以处理复杂的状态转移、跨账户的消息通信、甚至是基于特定条件的自动化操作。这使得Ton的账户模型比传统区块链上的账户模型更具扩展性和灵活性。

账本结构

Ton的账本结构设计为高效处理大规模并发交易,支持异步消息传递和多分片操作。每个账户的状态保存在Merkle树结构中,这使得Ton的账本具有高效的状态验证能力。

状态存储

账户的状态信息被存储在持久化存储中,并通过Merkle树进行组织,以确保状态的完整性和安全性。这种设计还支持状态的高效查询和验证,尤其是在跨分片交易的场景中。

帐户或智能合约状态通常包含以下内容:

1.基础货币的余额

2.其他货币的余额

3.智能合约代码(或其哈希)

4.智能合约的持久化数据(或其Merkle哈希)

5.有关持久化存储单元数和使用的原始字节数的统计信息

6.智能合约持久存储的付款的最近时间(实际上是主链块号)

7.转移货币并从此帐户发送消息所需的公钥(可选; 默认情况下等于 account_id 本身)。在某些情况下,类似于比特币交易输出所做的,可以在此处找到更复杂的签名检查代码; 然后 account_id 将等于此代码的哈希值。

并非所有的信息都是每个帐户必须需要的。例如,智能合约代码仅适用于智能合约,但不适用于“简单”账户。此外,虽然任何账户必须具有主要货币的非零余额(例如,基本工作链的主链和分片链的 Gram),但其它货币的余额可能为零。为了避免保留未使用的数据,在工作链的创建期间定义了一个 sum-product 类型,它使用不同的标记字节来区分不同的“够造函数“。最终,帐户状态本身被保存为 TVM 持久化存储的单元集合。

消息传递与处理

Ton的账本结构内置了对异步消息传递的支持,每个账户可以独立处理接收到的消息并更新其状态。这种异步消息机制允许账户之间进行复杂的交互,而不会因为某个操作的延迟而影响其他账户的正常运行。

Gas 模型

Ton(The Open Network)区块链通过其独特的 Gas 费模型大幅优化了智能合约的执行效率。Gas 费模型在区块链中用于衡量和限制智能合约执行过程中消耗的资源。与传统区块链(如以太坊)的 Gas 模型相比,Ton 的模型设计更为复杂且高效,能够更精确地管理合约执行过程中的资源消耗。

细化的Gas消耗测量

Ton的Gas模型能够精确测量智能合约在执行过程中消耗的计算资源、存储操作以及消息传递成本。通过对计算、存储和消息传递等资源的细化测量,Ton 的 Gas 模型能够防止某些复杂度过高的操作占用过多的资源。通过限制 Gas 消耗,Ton 确保了网络的每个节点都能公平地分配计算资源,避免单一合约或操作对网络资源的过度消耗。

并行处理与 Gas 优化

Ton 支持智能合约的并行处理,这使得多个合约能够同时在不同的分片上运行,而不会相互阻塞。在这种设计下,其 Gas 模型与其并行执行和分片机制紧密结合,通过在多个分片上并行处理合约,Ton 可以将 Gas 的计算和支付分散到不同的节点和链上,避免了网络拥堵,同时最大化了资源利用率。

动态 Gas 调整机制

Ton 的 Gas 模型中包含了动态调整机制,允许根据网络的实时负载情况对 Gas 费进行调整。这意味着在网络负载较低时,用户可以以较低的 Gas 费执行合约,从而鼓励在低负载时段进行操作,平衡网络的资源使用。这种机制不仅提升了用户体验,还通过市场化的方式控制了资源的使用峰值。

Ton 智能合约易忽略漏洞

在我们上一篇TON的安全分析文章中已经详细介绍了Ton生态的常规安全漏洞,也可参考下表:

TON智能合约的安全隐患与优化建议

TON智能合约的安全隐患与优化建议

本文将重点介绍我们团队总结出的TON合约中容易被忽略的漏洞点:

(1)代码可读性优化

在TON的智能合约中,会使用数字来存储消息发送的相关数据,例如下面的代码中,多次使用数字来表示对应的标识和数据存储长度,这样大大降低降低代码的可读性和可维护性。其他开发者在阅读这些代码时,很难理解这些数字的意义和用途。为了提高代码的可读性和可维护性,建议将关键的数字值定义为具名常量,例如:0x18定义为NON_BOUNCEABLE。

另外,在合约判断条件中的错误提示信息,同样建议定义对应的变量替换错误码。

TON智能合约的安全隐患与优化建议

(2)使用end_parse()确保数据完整性

在TON合约中,数据解析遵循固定的顺序,从原始数据中逐步加载指定类型的数据。这种解析方式确保了数据的一致性和准确性。如下所示:

TON智能合约的安全隐患与优化建议

注意这里的end_parse()用于检查数据切片(slice)是否为空,如果切片不为空,函数会抛出一个异常。这样可确保数据的格式和内容都是符合预期的。如果end_parse()函数发现数据切片中仍然有剩余的数据,这可能表明数据解析没有完全按照预期进行,或者数据的格式存在问题。因此,通过调用end_parse(),可以检查是否解析过程中数据有遗漏或异常。

(3)数据记载和存储类型不匹配引发的异常

这里主要需要说明的是int和uint的存取类型匹配,如下所示的代码中,数据存储时使用了store_int()来存储int类型的值为-42,但是却使用了load_uint()来加载这个值,这里就可能出现异常。

TON智能合约的安全隐患与优化建议

(4)inline_ref和inline修饰符的合理使用

首先,需要阐述一下inline_ref和inline修饰符的区别:

lInline:使用inline修饰符的函数,其代码会在每次调用时被直接插入到调用位置。也就是说,每次调用函数时,函数的实际代码会被复制到调用的位置,而不是像普通函数那样通过跳转到函数体执行。

linline_ref:使用 inline_ref修饰符的函数,其代码存储在一个独立的cell中。每次调用函数时,TVM通过CALLREF命令来执行存储在cell中的代码,而不是在调用位置插入函数代码。

所以,inline修饰符适用于简单函数,减少函数调用开销,但可能导致合约代码重复;而inline_ref 修饰符适用于较复杂或被多次调用的函数,通过将函数代码存储在单独的cell中来提高效率,避免了代码重复。那么可以总结为:当函数较大或被多个地方调用时,建议使用inline_ref;反之,则建议使用inline。

(5)确定正确的工作链

TON允许创建多达2^32条工作链,每条工作链则可以细分为多达2^60个分片,前只有2个工作链:主链(-1)和基本链(0)。合约中计算目标地址时,必须明确指定目标地址所属的链ID,以确保生成的钱包地址位于正确的工作链上。为了避免生成错误地址,建议使用 force_chain()强制指定链ID。

(6)避免错误码冲突

合约设计中,为了确保规范性和避免混淆,错误码的管理非常关键。对于TON智能合约,首先应确保每个错误码在合约中是唯一的,避免在同一个合约中定义重复的错误码,以防止错误码的混淆和信息的不明确;其次TON平台或底层系统已经定义了一些标准的错误码,应避免与这些系统错误码冲突,例如333错误码表示的链ID不匹配。所以建议合约的错误码最好在400到1000之间。

(7)操作完成后需要存储数据和调用return()

在TON智能合约中,消息处理会根据op-code选择不同的逻辑。完成对应业逻辑后,还需完成两项操作:首先,如果涉及数据更改,必须调用save_data()以确保数据被存储,否则更改将无效;其次,必须调用return()以表示该操作完成,否则将触发throw(0xffff)异常。

综上所述,TON 区块链凭借其创新的架构和灵活的开发环境,正逐渐成为去中心化应用开发者的理想平台。然而,随着智能合约在 TON 生态系统中扮演越来越重要的角色,合约安全性问题也不容忽视。开发者应深入了解TON 生态的特性,严格遵循最佳实践,强化安全审计流程,确保合约的稳健性与安全性。只有这样,才能充分发挥 TON 平台的优势,构建更加安全可靠的去中心化应用,为整个生态系统的健康发展保驾护航。

目前TON生态正在快速发展,吸引了大量的资金与活跃用户。然而,随之而来的安全问题也不容忽视。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1502

2023.10.24

登录token无效
登录token无效

登录token无效解决方法:1、检查token的有效期限,如果token已经过期,需要重新获取一个新的token;2、检查token的签名,如果签名不正确,需要重新获取一个新的token;3、检查密钥的正确性,如果密钥不正确,需要重新获取一个新的token;4、使用HTTPS协议传输token,建议使用HTTPS协议进行传输 ;5、使用双因素认证,双因素认证可以提高账户的安全性。

6193

2023.09.14

登录token无效怎么办
登录token无效怎么办

登录token无效的解决办法有检查Token是否过期、检查Token是否正确、检查Token是否被篡改、检查Token是否与用户匹配、清除缓存或Cookie、检查网络连接和服务器状态、重新登录或请求新的Token、联系技术支持或开发人员等。本专题为大家提供token相关的文章、下载、课程内容,供大家免费下载体验。

819

2023.09.14

token怎么获取
token怎么获取

获取token值的方法:1、小程序调用“wx.login()”获取 临时登录凭证code,并回传到开发者服务器;2、开发者服务器以code换取,用户唯一标识openid和会话密钥“session_key”。想了解更详细的内容,可以阅读本专题下面的文章。

1069

2023.12.21

token什么意思
token什么意思

token是一种用于表示用户权限、记录交易信息、支付虚拟货币的数字货币。可以用来在特定的网络上进行交易,用来购买或出售特定的虚拟货币,也可以用来支付特定的服务费用。想了解更多token什么意思的相关内容可以访问本专题下面的文章。

1358

2024.03.01

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

463

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

544

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

93

2025.08.29

java入门学习合集
java入门学习合集

本专题整合了java入门学习指南、初学者项目实战、入门到精通等等内容,阅读专题下面的文章了解更多详细学习方法。

1

2026.01.29

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
光速学会docker容器
光速学会docker容器

共33课时 | 1.9万人学习

go语言基础与基本函数
go语言基础与基本函数

共17课时 | 3.1万人学习

Css3入门视频教程
Css3入门视频教程

共21课时 | 3.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号