在區塊鏈技術蓬勃發展的當下,TON(The Open Network)憑藉其高效、彈性的特性,正吸引越來越多的開發者投入其中。平台獨特的架構為去中心化應用提供了豐富的工具與可能,但隨之而來的合約安全挑戰也不容忽視。本文將圍繞 TON 的核心特性、常見的安全隱患以及相應的優化建議展開闡述,協助開發者在編寫 FunC 合約時規避風險。
我們 Bitaigen 編輯團隊精心梳理了 TON 合約中易被忽視的安全盲點,並提供實用的防護與優化思路,協助開發者在 FunC 程式設計時提前規避風險,確保專案穩健運行,讓您快速掌握關鍵要點,提升開發效率。
Ton 智能合約易忽略漏洞
在之前的安全分析中,我們已經梳理了 TON 生態常見的漏洞類型(見下表),本文重點聚焦於那些容易被忽視但危害潛在的細節問題。


(1) 代碼可讀性與常量化
合約中常會出現硬編碼的數字,例如 `0x18` 用來標識 NON_BOUNCEABLE,這會導致後期維護困難。建議將這些關鍵數值抽象為具名常量,並在錯誤提示中使用統一的變數代替裸露的錯誤碼,以提升程式碼的可讀性和可維護性。

(2) 使用 `end_parse()` 保證解析完整
TON 合約在解析外部資料時遵循固定順序,逐段讀取指定類型的欄位。`end_parse()` 用於檢測切片是否已經耗盡,若仍有餘量則拋出例外,從而確保資料結構嚴格符合預期,避免因解析不完整導致的邏輯錯誤。

(3) 資料類型匹配錯誤
在存取整數時,必須保持型別的一致性。例如,使用 `store_int()` 寫入 `-42` 後,若隨後使用 `load_uint()` 讀取,就會產生例外。務必確保存儲與讀取使用相同的有號或無號類型。

(4) `inline` 與 `inline_ref` 的適用情境
- inline:函式體在每次呼叫時直接內嵌,適合短小、呼叫頻率高的程式碼,但會導致程式碼膨脹。
- inline_ref:函式程式碼存放於獨立的 cell 中,透過 `CALLREF` 呼叫,適用於體積較大或被多處重複使用的函式,可有效降低重覆程式碼。
綜合考量函式大小與呼叫次數,建議對複雜或多次使用的函式採用 `inline_ref`,對輕量函式使用 `inline`。
(5) 明確工作鏈 ID
TON 支援最多 2^32 條工作鏈,每條工作鏈可進一步細分為 2^60 個分片。合約在產生目標地址時必須指明所屬鏈的 ID,防止地址落在錯誤的工作鏈上。使用 `force_chain()` 強制設定鏈 ID 是一種可靠的做法。
(6) 錯誤碼的唯一性與衝突規避
錯誤碼應在合約內部保持唯一,避免重複定義導致的歧義。同時,需要避開平台已定義的標準錯誤碼(如 333 表示鏈 ID 不匹配)。推薦將自訂錯誤碼設定在 400‑1000 區間,以降低衝突機率。
(7) 完成操作後務必保存並返回
合約在處理不同 `op-code` 時,若涉及狀態修改,需要呼叫 `save_data()` 將變更寫入永久儲存;隨後必須執行 `return()` 表示邏輯已正常結束。若遺漏 `return()`,系統會觸發 `throw(0xffff)` 例外,導致交易回滾。
※依據臺灣金管會相關規範,請自行評估法規風險。
---
Ton 非同步特性與帳戶機制解析
網路分片與非同步通訊
TON 網路劃分為三層鏈結構:主鏈(Masterchain)、工作鏈(Workingchains) 與 分片鏈(Shardchains)。
- 主鏈 負責全網元資料與共識,記錄所有工作鏈與分片鏈的狀態,確保整體安全與一致性。
- 工作鏈 是獨立的區塊鏈,數量上限為 2^32 條,每條鏈可針對特定業務或合約進行客製化。
- 分片鏈 為工作鏈的子鏈,最多可拆分為 2^60 條,承擔平行處理交易的職責,從而提升吞吐量。
理論上,每個帳戶可以獨占一條分片鏈,擁有獨立的 COIN/TOKEN 餘額,帳戶之間的交易可以完全平行執行。訊息在分片間的傳遞路徑為 log₁₆(N)‑1(N 為分片鏈總數),實現高效的非同步通訊。

圖源:https://frontierlabzh.medium.com/ton-web3世界的weixin-e1d3ae3b3574
合約互動的訊息機制
在 TON 中,合約之間透過 內部訊息(合約內部交互)或 外部訊息(外部實體發起)進行通訊。發送方無需等待接收方的即時回應即可繼續執行後續邏輯,這種非同步模型相較於以太坊的同步呼叫,顯著提升了彈性與擴充性,卻也帶來了併發與競爭條件的管理難題。
訊息格式
每條訊息通常包含發送者、接收者、轉帳金額以及訊息體。訊息體可以承載函式呼叫、資料傳輸或自訂指令,格式上具備高度可擴充性,滿足不同合約間的多樣化需求。

訊息佇列與狀態處理
每個合約內部維護一個待處理的訊息佇列,執行時依序取出並處理。由於處理是非同步的,合約狀態僅在對應訊息被消費後才會更新,這要求開發者在設計時充分考量狀態的一致性。
非同步優勢
- 高效分片:非同步機制與分片設計天然契合,分片獨立處理訊息,避免跨分片同步導致的延遲。
- 資源利用:無需在單一區塊內完成全部計算,合約執行可分散到多個區塊,降低峰值資源消耗。
- 容錯性:即便某個合約因資源限制未及時回應,發送方仍可繼續執行其他邏輯,系統整體不會因單點延遲而停滯。
設計挑戰
- 狀態一致性:非同步訊息可能在不同時間點到達,導致狀態變更順序不確定,需要在合約中加入防護措施確保最終一致性。
- 競爭條件:多條訊息併發修改同一狀態時,需使用鎖或交易機制防止衝突。
- 安全風險:跨合約通訊易受到中間人或重放攻擊,建議加入時間戳、隨機數或多簽等防禦手段。
---
帳本模型與帳戶抽象
帳戶抽象
TON 採用基於合約的帳戶模型,每個帳戶本質上是一個包含 Code、Data、Message Handling 三部分的合約。地址由程式碼雜湊、部署時的初始資料以及其他參數組合產生,同一程式碼在不同分片或鏈上可能得到不同的地址。此設計使得帳戶不僅是資產的容器,還可以實現複雜的業務邏輯、跨帳戶訊息以及條件觸發的自動化操作,較傳統模型擁有更高的可擴充性。
帳本結構
帳戶狀態透過 Merkle 樹 進行組織與永久化,既保證了資料完整性,又便於高效驗證。狀態條目主要包括:
- 主幣餘額
- 其他代幣餘額
- 合約程式碼(或其雜湊)
- 永久化資料(或 Merkle 雜湊)
- 儲存單元數與原始位元組統計
- 最近一次付款的主鏈區塊號
- 用於轉帳的公鑰(可選,預設等於 `account_id`)
並非所有欄位對每個帳戶都必需,例如普通帳戶無需存放合約程式碼。工作鏈建立時透過 `sum-product` 類型標記區分不同建構子,最終狀態以 TVM 永久化儲存單元集合的形式保存。
訊息處理
帳本層面內建對非同步訊息的支援,每個帳戶可以獨立接收並處理訊息,狀態更新僅在訊息被消費後進行,從而實現高併發的互動而不互相阻塞。
---
Gas 模型的特點
TON 的 Gas 費用模型在資源計量與分配上更加細緻。它能夠分別衡量 計算、儲存、訊息傳遞 三類資源的消耗,防止單一合約佔用過多算力或儲存空間。
- 平行執行:得益於分片, 多個合約可以在不同分片上
相關閱讀
💡 註冊幣安使用邀請碼 B2345 享平台手續費折扣。詳見 幣安完整教學。