在區(qū)塊鏈技術(shù)快速發(fā)展的今天,ton (the open network) 作為一款高效且靈活的區(qū)塊鏈平臺(tái),正受到越來(lái)越多開(kāi)發(fā)者的關(guān)注。ton 的獨(dú)特架構(gòu)和特性為去中心化應(yīng)用的開(kāi)發(fā)提供了強(qiáng)大的工具和豐富的可能性。
然而,隨著功能和復(fù)雜性的增加,智能合約的安全性也變得越來(lái)越重要。FunC 作為 TON 上的智能合約編程語(yǔ)言,以其靈活性和高效性著稱,但同時(shí)也帶來(lái)了許多潛在的風(fēng)險(xiǎn)和挑戰(zhàn)。編寫安全可靠的智能合約,需要開(kāi)發(fā)者深刻理解 FunC 語(yǔ)言的特性以及可能存在的風(fēng)險(xiǎn)。
本文將詳細(xì)分析在 TON 區(qū)塊鏈上的一些與智能合約有關(guān)的特性,以及TON上智能合約容易被忽略的漏洞點(diǎn)。
Ton 異步特性與賬戶機(jī)制解析
智能合約異步調(diào)用
網(wǎng)絡(luò)分片與異步通信
TON 區(qū)塊鏈在設(shè)計(jì)上分為三種鏈:主鏈(Masterchain),工作鏈(Workingchains)和分片鏈(Shardchains)。
主鏈?zhǔn)钦麄€(gè)網(wǎng)絡(luò)的核心,負(fù)責(zé)存儲(chǔ)全網(wǎng)的元數(shù)據(jù)和共識(shí)機(jī)制。它記錄所有工作鏈和分片鏈的狀態(tài),并確保全網(wǎng)的一致性和安全性。工作鏈?zhǔn)仟?dú)立的區(qū)塊鏈,最多有 2^32條,負(fù)責(zé)處理特定類型的交易和智能合約。每個(gè)工作鏈可以有自己的規(guī)則和特性,以滿足不同的應(yīng)用需求。分片鏈?zhǔn)枪ぷ麈湹淖渔湥糜谶M(jìn)一步分割工作鏈的負(fù)載,提升處理能力和擴(kuò)展性。每個(gè)工作鏈最多拆分為 2^60 個(gè) shard chain,分片鏈獨(dú)立處理部分交易,從而實(shí)現(xiàn)高效的并行處理。
理論上每一個(gè)賬戶都可以獨(dú)占一個(gè) shard chain,每一個(gè)賬戶獨(dú)立維護(hù)自己的 COIN/TOKEN 余額,每一個(gè)賬戶間的交易都可以完全并行。賬戶與賬戶間通過(guò)異步消息進(jìn)行傳遞,消息在 shard chain 間傳遞的路徑為 log_16(N) - 1,其中 N 為 shard chain 的數(shù)量。
圖源:https://frontierlabzh.medium.com/ton-web3世界的weixin-e1d3ae3b3574
在Ton中,智能合約通過(guò)發(fā)送和接收消息進(jìn)行交互。這些消息可以是內(nèi)部消息(一般來(lái)說(shuō)是智能合約互相交互所發(fā)送的消息)或外部消息(由外部來(lái)源發(fā)送的消息)。消息的傳遞過(guò)程不需要等待目標(biāo)合約的立即響應(yīng),發(fā)送方可以繼續(xù)執(zhí)行其余的邏輯代碼。這種異步消息傳遞機(jī)制相較于以太坊的同步調(diào)用,提供了更高的靈活性和擴(kuò)展性,減少了因等待響應(yīng)導(dǎo)致的性能瓶頸,同時(shí)也帶來(lái)了處理并發(fā)和競(jìng)爭(zhēng)條件的挑戰(zhàn)。
消息格式與結(jié)構(gòu)
在Ton中,消息通常包含發(fā)件人、收件人、金額、消息體等信息。消息體可以是函數(shù)調(diào)用、數(shù)據(jù)傳輸或其他自定義內(nèi)容。Ton使用的消息格式可以靈活定義和擴(kuò)展,使得不同合約之間能夠高效傳遞各種類型的信息。
消息隊(duì)列與狀態(tài)處理
每個(gè)合約都維護(hù)一個(gè)消息隊(duì)列,存儲(chǔ)尚未處理的消息。合約在執(zhí)行過(guò)程中,會(huì)根據(jù)隊(duì)列中的消息逐個(gè)處理。由于消息處理是異步的,合約的狀態(tài)在收到消息之前不會(huì)立即更新。
異步消息傳遞的優(yōu)勢(shì)
?高效的分片機(jī)制:Ton的異步機(jī)制與其分片設(shè)計(jì)高度契合。每個(gè)分片獨(dú)立處理合約的消息和狀態(tài)變化,避免了跨分片同步通信帶來(lái)的延遲問(wèn)題。這種設(shè)計(jì)提升了整個(gè)網(wǎng)絡(luò)的吞吐量和可擴(kuò)展性。
?降低資源消耗:由于異步消息不要求即時(shí)響應(yīng),Ton的合約執(zhí)行可以分散在多個(gè)區(qū)塊內(nèi)完成,避免了單個(gè)區(qū)塊內(nèi)資源的過(guò)度消耗。這使得Ton能夠支持更為復(fù)雜和資源密集型的智能合約。
?容錯(cuò)性與可靠性:異步消息的傳遞機(jī)制使得系統(tǒng)更具容錯(cuò)性。例如,如果某個(gè)合約由于資源限制或其他原因無(wú)法及時(shí)響應(yīng)消息,發(fā)送方仍然可以繼續(xù)處理其他邏輯,系統(tǒng)不會(huì)因?yàn)閱蝹€(gè)合約的延遲而停滯。
異步合約設(shè)計(jì)的挑戰(zhàn)
?狀態(tài)一致性問(wèn)題:由于消息傳遞是異步的,合約的狀態(tài)在不同時(shí)刻可能會(huì)接收到不同的消息,這需要開(kāi)發(fā)者特別注意狀態(tài)一致性問(wèn)題。在設(shè)計(jì)合約時(shí),必須考慮到不同消息順序可能帶來(lái)的狀態(tài)變化,確保系統(tǒng)在任何情況下都能保持一致性。
?競(jìng)爭(zhēng)條件與防護(hù):異步消息處理帶來(lái)了潛在的競(jìng)爭(zhēng)條件問(wèn)題,多個(gè)消息可能同時(shí)嘗試修改合約狀態(tài)。開(kāi)發(fā)者需要引入適當(dāng)?shù)逆i機(jī)制或使用事務(wù)性操作來(lái)防止?fàn)顟B(tài)沖突。
?安全性考量:異步合約在處理跨合約通信時(shí),容易受到中間人攻擊或重放攻擊。因此,在設(shè)計(jì)異步合約時(shí),必須考慮到這些潛在的安全風(fēng)險(xiǎn),并采取措施防止它們發(fā)生,如使用時(shí)間戳、隨機(jī)數(shù)或多重簽名等手段。
賬本模型
Ton(The Open Network)在設(shè)計(jì)其區(qū)塊鏈基礎(chǔ)設(shè)施時(shí),采用了一種獨(dú)特的賬戶抽象和賬本模型。這個(gè)模型的靈活性體現(xiàn)在它如何處理賬戶的狀態(tài)、消息傳遞以及合約的執(zhí)行。
賬戶抽象
Ton的賬戶模型采用了一種基于合約的抽象,每個(gè)賬戶都可以視為一個(gè)合約,這與以太坊的賬戶抽象模型有一些相似之處,但更加靈活和通用。在Ton中,賬戶不僅僅是持有資產(chǎn)的容器,它們還包含了合約代碼和狀態(tài)數(shù)據(jù)。每個(gè)賬戶都由其代碼(Code)、數(shù)據(jù)(Data)和消息處理(Message Handling)邏輯組成。
賬戶結(jié)構(gòu):每個(gè)Ton賬戶都有一個(gè)唯一的地址,該地址是由賬戶代碼的哈希值、部署時(shí)的初始數(shù)據(jù)以及一些其他參數(shù)組合而成的。這意味著同樣的代碼和初始數(shù)據(jù)部署在不同的環(huán)境下(例如,不同的區(qū)塊鏈或分片)可能會(huì)生成不同的地址。
靈活性:由于每個(gè)賬戶都可以運(yùn)行自己的合約代碼,因此Ton的賬戶可以實(shí)現(xiàn)非常復(fù)雜的邏輯。賬戶不僅僅是簡(jiǎn)單的余額持有者,還可以處理復(fù)雜的狀態(tài)轉(zhuǎn)移、跨賬戶的消息通信、甚至是基于特定條件的自動(dòng)化操作。這使得Ton的賬戶模型比傳統(tǒng)區(qū)塊鏈上的賬戶模型更具擴(kuò)展性和靈活性。
賬本結(jié)構(gòu)
Ton的賬本結(jié)構(gòu)設(shè)計(jì)為高效處理大規(guī)模并發(fā)交易,支持異步消息傳遞和多分片操作。每個(gè)賬戶的狀態(tài)保存在Merkle樹結(jié)構(gòu)中,這使得Ton的賬本具有高效的狀態(tài)驗(yàn)證能力。
狀態(tài)存儲(chǔ)
賬戶的狀態(tài)信息被存儲(chǔ)在持久化存儲(chǔ)中,并通過(guò)Merkle樹進(jìn)行組織,以確保狀態(tài)的完整性和安全性。這種設(shè)計(jì)還支持狀態(tài)的高效查詢和驗(yàn)證,尤其是在跨分片交易的場(chǎng)景中。
帳戶或智能合約狀態(tài)通常包含以下內(nèi)容:
1.基礎(chǔ)貨幣的余額
2.其他貨幣的余額
3.智能合約代碼(或其哈希)
4.智能合約的持久化數(shù)據(jù)(或其Merkle哈希)
5.有關(guān)持久化存儲(chǔ)單元數(shù)和使用的原始字節(jié)數(shù)的統(tǒng)計(jì)信息
6.智能合約持久存儲(chǔ)的付款的最近時(shí)間(實(shí)際上是主鏈塊號(hào))
7.轉(zhuǎn)移貨幣并從此帳戶發(fā)送消息所需的公鑰(可選; 默認(rèn)情況下等于 account_id 本身)。在某些情況下,類似于比特幣交易輸出所做的,可以在此處找到更復(fù)雜的簽名檢查代碼; 然后 account_id 將等于此代碼的哈希值。
并非所有的信息都是每個(gè)帳戶必須需要的。例如,智能合約代碼僅適用于智能合約,但不適用于“簡(jiǎn)單”賬戶。此外,雖然任何賬戶必須具有主要貨幣的非零余額(例如,基本工作鏈的主鏈和分片鏈的 Gram),但其它貨幣的余額可能為零。為了避免保留未使用的數(shù)據(jù),在工作鏈的創(chuàng)建期間定義了一個(gè) sum-product 類型,它使用不同的標(biāo)記字節(jié)來(lái)區(qū)分不同的“夠造函數(shù)“。最終,帳戶狀態(tài)本身被保存為 TVM 持久化存儲(chǔ)的單元集合。
消息傳遞與處理
Ton的賬本結(jié)構(gòu)內(nèi)置了對(duì)異步消息傳遞的支持,每個(gè)賬戶可以獨(dú)立處理接收到的消息并更新其狀態(tài)。這種異步消息機(jī)制允許賬戶之間進(jìn)行復(fù)雜的交互,而不會(huì)因?yàn)槟硞€(gè)操作的延遲而影響其他賬戶的正常運(yùn)行。
Gas 模型
Ton(The Open Network)區(qū)塊鏈通過(guò)其獨(dú)特的 Gas 費(fèi)模型大幅優(yōu)化了智能合約的執(zhí)行效率。Gas 費(fèi)模型在區(qū)塊鏈中用于衡量和限制智能合約執(zhí)行過(guò)程中消耗的資源。與傳統(tǒng)區(qū)塊鏈(如以太坊)的 Gas 模型相比,Ton 的模型設(shè)計(jì)更為復(fù)雜且高效,能夠更精確地管理合約執(zhí)行過(guò)程中的資源消耗。
細(xì)化的Gas消耗測(cè)量
Ton的Gas模型能夠精確測(cè)量智能合約在執(zhí)行過(guò)程中消耗的計(jì)算資源、存儲(chǔ)操作以及消息傳遞成本。通過(guò)對(duì)計(jì)算、存儲(chǔ)和消息傳遞等資源的細(xì)化測(cè)量,Ton 的 Gas 模型能夠防止某些復(fù)雜度過(guò)高的操作占用過(guò)多的資源。通過(guò)限制 Gas 消耗,Ton 確保了網(wǎng)絡(luò)的每個(gè)節(jié)點(diǎn)都能公平地分配計(jì)算資源,避免單一合約或操作對(duì)網(wǎng)絡(luò)資源的過(guò)度消耗。
并行處理與 Gas 優(yōu)化
Ton 支持智能合約的并行處理,這使得多個(gè)合約能夠同時(shí)在不同的分片上運(yùn)行,而不會(huì)相互阻塞。在這種設(shè)計(jì)下,其 Gas 模型與其并行執(zhí)行和分片機(jī)制緊密結(jié)合,通過(guò)在多個(gè)分片上并行處理合約,Ton 可以將 Gas 的計(jì)算和支付分散到不同的節(jié)點(diǎn)和鏈上,避免了網(wǎng)絡(luò)擁堵,同時(shí)最大化了資源利用率。
動(dòng)態(tài) Gas 調(diào)整機(jī)制
Ton 的 Gas 模型中包含了動(dòng)態(tài)調(diào)整機(jī)制,允許根據(jù)網(wǎng)絡(luò)的實(shí)時(shí)負(fù)載情況對(duì) Gas 費(fèi)進(jìn)行調(diào)整。這意味著在網(wǎng)絡(luò)負(fù)載較低時(shí),用戶可以以較低的 Gas 費(fèi)執(zhí)行合約,從而鼓勵(lì)在低負(fù)載時(shí)段進(jìn)行操作,平衡網(wǎng)絡(luò)的資源使用。這種機(jī)制不僅提升了用戶體驗(yàn),還通過(guò)市場(chǎng)化的方式控制了資源的使用峰值。
Ton 智能合約易忽略漏洞
在我們上一篇TON的安全分析文章中已經(jīng)詳細(xì)介紹了Ton生態(tài)的常規(guī)安全漏洞,也可參考下表:
本文將重點(diǎn)介紹我們團(tuán)隊(duì)總結(jié)出的TON合約中容易被忽略的漏洞點(diǎn):
(1)代碼可讀性優(yōu)化
在TON的智能合約中,會(huì)使用數(shù)字來(lái)存儲(chǔ)消息發(fā)送的相關(guān)數(shù)據(jù),例如下面的代碼中,多次使用數(shù)字來(lái)表示對(duì)應(yīng)的標(biāo)識(shí)和數(shù)據(jù)存儲(chǔ)長(zhǎng)度,這樣大大降低降低代碼的可讀性和可維護(hù)性。其他開(kāi)發(fā)者在閱讀這些代碼時(shí),很難理解這些數(shù)字的意義和用途。為了提高代碼的可讀性和可維護(hù)性,建議將關(guān)鍵的數(shù)字值定義為具名常量,例如:0x18定義為NON_BOUNCEABLE。
另外,在合約判斷條件中的錯(cuò)誤提示信息,同樣建議定義對(duì)應(yīng)的變量替換錯(cuò)誤碼。
(2)使用end_parse()確保數(shù)據(jù)完整性
在TON合約中,數(shù)據(jù)解析遵循固定的順序,從原始數(shù)據(jù)中逐步加載指定類型的數(shù)據(jù)。這種解析方式確保了數(shù)據(jù)的一致性和準(zhǔn)確性。如下所示:
注意這里的end_parse()用于檢查數(shù)據(jù)切片(slice)是否為空,如果切片不為空,函數(shù)會(huì)拋出一個(gè)異常。這樣可確保數(shù)據(jù)的格式和內(nèi)容都是符合預(yù)期的。如果end_parse()函數(shù)發(fā)現(xiàn)數(shù)據(jù)切片中仍然有剩余的數(shù)據(jù),這可能表明數(shù)據(jù)解析沒(méi)有完全按照預(yù)期進(jìn)行,或者數(shù)據(jù)的格式存在問(wèn)題。因此,通過(guò)調(diào)用end_parse(),可以檢查是否解析過(guò)程中數(shù)據(jù)有遺漏或異常。
(3)數(shù)據(jù)記載和存儲(chǔ)類型不匹配引發(fā)的異常
這里主要需要說(shuō)明的是int和uint的存取類型匹配,如下所示的代碼中,數(shù)據(jù)存儲(chǔ)時(shí)使用了store_int()來(lái)存儲(chǔ)int類型的值為-42,但是卻使用了load_uint()來(lái)加載這個(gè)值,這里就可能出現(xiàn)異常。
(4)inline_ref和inline修飾符的合理使用
首先,需要闡述一下inline_ref和inline修飾符的區(qū)別:
lInline:使用inline修飾符的函數(shù),其代碼會(huì)在每次調(diào)用時(shí)被直接插入到調(diào)用位置。也就是說(shuō),每次調(diào)用函數(shù)時(shí),函數(shù)的實(shí)際代碼會(huì)被復(fù)制到調(diào)用的位置,而不是像普通函數(shù)那樣通過(guò)跳轉(zhuǎn)到函數(shù)體執(zhí)行。
linline_ref:使用 inline_ref修飾符的函數(shù),其代碼存儲(chǔ)在一個(gè)獨(dú)立的cell中。每次調(diào)用函數(shù)時(shí),TVM通過(guò)CALLREF命令來(lái)執(zhí)行存儲(chǔ)在cell中的代碼,而不是在調(diào)用位置插入函數(shù)代碼。
所以,inline修飾符適用于簡(jiǎn)單函數(shù),減少函數(shù)調(diào)用開(kāi)銷,但可能導(dǎo)致合約代碼重復(fù);而inline_ref 修飾符適用于較復(fù)雜或被多次調(diào)用的函數(shù),通過(guò)將函數(shù)代碼存儲(chǔ)在單獨(dú)的cell中來(lái)提高效率,避免了代碼重復(fù)。那么可以總結(jié)為:當(dāng)函數(shù)較大或被多個(gè)地方調(diào)用時(shí),建議使用inline_ref;反之,則建議使用inline。
(5)確定正確的工作鏈
TON允許創(chuàng)建多達(dá)2^32條工作鏈,每條工作鏈則可以細(xì)分為多達(dá)2^60個(gè)分片,前只有2個(gè)工作鏈:主鏈(-1)和基本鏈(0)。合約中計(jì)算目標(biāo)地址時(shí),必須明確指定目標(biāo)地址所屬的鏈ID,以確保生成的錢包地址位于正確的工作鏈上。為了避免生成錯(cuò)誤地址,建議使用 force_chain()強(qiáng)制指定鏈ID。
(6)避免錯(cuò)誤碼沖突
合約設(shè)計(jì)中,為了確保規(guī)范性和避免混淆,錯(cuò)誤碼的管理非常關(guān)鍵。對(duì)于TON智能合約,首先應(yīng)確保每個(gè)錯(cuò)誤碼在合約中是唯一的,避免在同一個(gè)合約中定義重復(fù)的錯(cuò)誤碼,以防止錯(cuò)誤碼的混淆和信息的不明確;其次TON平臺(tái)或底層系統(tǒng)已經(jīng)定義了一些標(biāo)準(zhǔn)的錯(cuò)誤碼,應(yīng)避免與這些系統(tǒng)錯(cuò)誤碼沖突,例如333錯(cuò)誤碼表示的鏈ID不匹配。所以建議合約的錯(cuò)誤碼最好在400到1000之間。
(7)操作完成后需要存儲(chǔ)數(shù)據(jù)和調(diào)用return()
在TON智能合約中,消息處理會(huì)根據(jù)op-code選擇不同的邏輯。完成對(duì)應(yīng)業(yè)邏輯后,還需完成兩項(xiàng)操作:首先,如果涉及數(shù)據(jù)更改,必須調(diào)用save_data()以確保數(shù)據(jù)被存儲(chǔ),否則更改將無(wú)效;其次,必須調(diào)用return()以表示該操作完成,否則將觸發(fā)throw(0xffff)異常。
綜上所述,TON 區(qū)塊鏈憑借其創(chuàng)新的架構(gòu)和靈活的開(kāi)發(fā)環(huán)境,正逐漸成為去中心化應(yīng)用開(kāi)發(fā)者的理想平臺(tái)。然而,隨著智能合約在 TON 生態(tài)系統(tǒng)中扮演越來(lái)越重要的角色,合約安全性問(wèn)題也不容忽視。開(kāi)發(fā)者應(yīng)深入了解TON 生態(tài)的特性,嚴(yán)格遵循最佳實(shí)踐,強(qiáng)化安全審計(jì)流程,確保合約的穩(wěn)健性與安全性。只有這樣,才能充分發(fā)揮 TON 平臺(tái)的優(yōu)勢(shì),構(gòu)建更加安全可靠的去中心化應(yīng)用,為整個(gè)生態(tài)系統(tǒng)的健康發(fā)展保駕護(hù)航。
目前TON生態(tài)正在快速發(fā)展,吸引了大量的資金與活躍用戶。然而,隨之而來(lái)的安全問(wèn)題也不容忽視。
以上就是TON智能合約的安全隱患與優(yōu)化建議的詳細(xì)內(nèi)容,更多請(qǐng)關(guān)注本站其它相關(guān)文章!
鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請(qǐng)第一時(shí)間聯(lián)系我們修改或刪除,多謝。