作者:@Web3Mario
引言:隨着幣安上線TON生態最大的遊戲Notcoin以及由全流通token經濟模型所引發的巨量財富效應,TON在短時間內即取得了極大的關注。和朋友聊了下得知TON的技術門檻比較高,而且DApp開發範式與主流公鏈協議有很大的差異,因此花了一些時間深入研究了一下相關課題,有些心得體會,與諸君分享。簡而言之,TON的核心設計理念是以一種“自下而上”的方式重構傳統的區塊鏈協議,並以捨棄互操作性爲代價,實現對高併發和高可擴展性的極致追求。
TON的核心設計思想——高併發與高可擴展性
可以這麼說,TON中所有複雜的技術選型的目的都來自於對高併發與高可擴展性的追求,當然從其誕生的背景我們也不難理解這一點。TON,即The Open Network,是一個去中心化的計算網絡,包含一個L1區塊鏈和多個組件。TON最初由Telegram的創始人Nikolai Durov及其團隊共同開發,而發展到現在則由全球獨立貢獻者的社區支持並維護。其誕生要追溯到2017年,Telegram團隊開始爲自己探索區塊鏈解決方案。由於當時沒有現有的L1區塊鏈能夠支持Telegram的九位數用戶基礎,他們決定設計自己的區塊鏈,當時稱爲Telegram Open Network。時間來到了2018年,爲了獲得實現TON所需的資源,Telegram在2018年第一季度發起了Gram代幣(後來改名爲Toncoin)的銷售。2020年由於監管問題,Telegram團隊退出了TON項目。隨後,一小部分開源開發者和Telegram比賽獲勝者接手了TON的代碼庫,將項目名稱更名爲The Open Network,並繼續積極地開發區塊鏈至今,且遵循原始TON白皮書中概述的原則。
那麼既然是以作爲Telegram的去中心化執行環境作爲設計目標,自然要面對兩個問題,高併發請求與海量數據,我們知道隨着技術發展到現在,號稱TPS最高的Solana實測最高TPS也只有65000,這顯然不足以支撐百萬級TPS要求的Telegram生態。與此同時隨着Telegram的大規模應用,其產生的數據量早已突破天際,而區塊鏈作爲一個極度冗餘的分佈式系統,若要求網絡中每個節點都保存一份完整的數據,這也是不現實的。
因此爲了解決上述兩個問題,TON對主流的區塊鏈協議做出了兩個方面的優化:
通過採用“無限分片範式”(Infinite Sharding Paradigm)設計系統,解決數據冗餘問題,使其可以承載大數據,同時緩解性能瓶頸問題;
通過引入基於Actor模型的完全並行執行環境,極大的提升網絡TPS;
做區塊鏈的鏈——通過無限分片能力讓每個賬戶都有一條專屬的賬戶鏈
當下我們知道,分片(sharding)已經成爲了大部分區塊鏈協議提升性能降低成本的主流方案,而TON則將這點做到了極致,並提出了無限分片範式,所謂無限分片範式,指的是允許區塊鏈根據網絡負載動態地增加或減少分片數量。這種範式使得TON能夠在保持高性能的同時,處理大規模的交易和智能合約操作,理論上TON可以爲每個賬戶都建立一條專屬的賬戶鏈,並通過一定的規則保證這些鏈之間的一致性,
抽象的來理解,在TON中一共存在四層鏈結構:
賬戶鏈(AccountChain):該層鏈表示與某個賬戶相關的一系列交易所組成的鏈,之所以交易可以組成鏈式結構,是因爲對於一個狀態機來說,只要執行規則一致,狀態機在接收到相同順序的指令後得到的結果是一致的,因此所有區塊鏈分佈式系統中都需要對交易進行鏈式排序,TON也不例外。賬戶鏈是TON網絡中最基本的組成單元,通常情況下賬戶鏈是一個虛擬的概念,不太可能真正存在一個獨立的賬戶鏈。
分片鏈(ShardChain):在大部分的語境下,分片鏈纔是TON中實際的組成單元,所謂分片鏈,即爲一組賬戶鏈的集合。
工作鏈(WorkChain):也可以叫做一組有自定義規則的分片鏈,例如創建一個基於EVM的工作鏈,在其上運行Solidity智能合約。理論上,社區中的每個人都可以創建自己的工作鏈。事實上,構建它是一個相當複雜的任務,在此之前還要支付創建它的(昂貴)費用,並獲得驗證者的2/3的票數來批准創建你的工作鏈。
主鏈(MasterChain):最後在TON中有一條特殊的鏈被稱爲主鏈,該鏈負責爲所有分片鏈帶來最終性。一旦分片鏈的區塊的哈希值被合併到主鏈的區塊中,該分片鏈區塊及其所有父區塊被認爲具有最終性,這意味着它們可以被認爲是固定且不可變的內容,而被所有分片鏈的後續區塊引用。
通過採用這樣的範式,使TON網絡具備以下三個特點:
動態分片: TON可以自動拆分和合並分片鏈以適應負載的變化。這意味着新塊總是快速生成,而交易不會產生很長的等待時間。
高度可擴展:通過無限分片範式,TON能夠支持幾乎無限數量的分片,理論上可以達到2的60次方個工作鏈。
自適應性: 當網絡中的某個部分負載增加時,該部分可以被細分成更多的分片來處理增加的交易量。相反,當負載減少時,分片可以合併以提高效率。
那麼這樣一個多鏈系統,首先需要面臨的就是跨鏈通信問題,尤其是由於具有無限分片的能力,當網絡中的分片數量達到一定量級後,鏈與鏈之間的信息路由將成爲一件困難的事情。試想一下網絡中共有4個節點,每個節點負責維護1條獨立的工作鏈,其中鏈接關係表示該節點除了負責自身的工作鏈中交易排序工作之外,還需要監聽並處理目標鏈中狀態變化,在TON中具體通過監聽輸出隊列的消息實現,
假設工作鏈1中的賬戶A希望向工作鏈3中的賬戶C發送一個消息。則需要設計到消息路由問題,在這個例子中有兩條路由路徑,工作鏈1 -> 工作鏈2-> 工作鏈3,工作鏈1 -> 工作鏈4 -> 工作鏈3。
當面臨更復雜的情況時,就需要一個高效且低成本的路由算法快速完成消息通信,TON選擇了所謂“超立方體路由算法”來實現跨鏈消息通信路由發現。所謂超立方體結構指的是一種特殊的網絡拓撲結構,一個n維超立方體是由2^n個頂點組成的,每個頂點都可以通過一個n位的二進制數來唯一標識。在這個結構中,任意兩個頂點如果在二進制表示中只有一位不同,那麼它們就是相鄰的。例如,在一個3維超立方體中,頂點000和頂點001是相鄰的,因爲它們只在最後一位上不同。而上述例子即是一個2維超立方體。
在超立方體路由協議中,消息將從源工作鏈到目標工作鏈的路由過程是通過比較源工作鏈和目標工作鏈地址的二進制表示來進行的。路由算法會找到這兩個地址之間的最小距離(即二進制表示中不同位的數量),並通過相鄰工作鏈逐步轉發信息,直到達到目標工作鏈。這種方法能夠確保數據包沿着最短路徑傳輸,從而提高了網絡的通信效率。
當然爲了簡化這個過程,TON也提出了一個樂觀技術方案,當用戶可以提供對某個路由路徑的有效證明,這通常是某個merkle trie root,節點即可直接承認該用戶提交的消息的可信性,這也被稱爲即時超立方體路由。
因此我們可以看到TON中的地址和其他區塊鏈協議有着明顯的區別,其他主流區塊鏈協議大都採用橢圓加密算法生成的公私鑰中公鑰對應的哈希作爲地址,因爲地址只是做唯一性區分,而不需要承載路由尋址的功能,而TON中的地址有兩部分組成,(workchain_id, account_id),其中workchain_id即按照超立方體路由算法地址進行編碼,在這裏就不詳細展開了。
還有一個容易產生疑問的點,你可能已經發覺到主鏈和每個工作鏈均有鏈接關係,那麼所有跨鏈信息均通過主鏈做中繼不就可以了麼,就像是cosmos那樣。在TON的設計理念中,主鏈僅用於處理最關鍵的任務,即維護衆多工作鏈的最終性,將消息通過主鏈做路由也不是不行,只是由此產生的手續費用將十分昂貴。
最後簡單提一下其共識算法,TON採用了BFT+PoS的方式,即任意staker均有機會參與區塊打包,TON的選舉治理合約會每隔一段時間,從所有Stakers中隨機選擇一個打包的驗證者集羣,被選中稱爲驗證者的節點將通過BFT算法打包出塊,若打包錯誤信息或作惡,其stake的token將會被罰沒,反之將得到出塊獎勵。這基本上已經是一個比較常見的選擇了,因此不在這裏展開介紹。
基於Actor模型的智能合約和完全並行執行環境
TON中另一個與主流區塊鏈協議不同的點是其智能合約執行環境。爲了突破主流區塊鏈協議TPS的限制,TON採用了自下而上的設計思路,採用Actor模型重構了智能合約及其執行方式,使其具備了完全並行執行的能力。
我們知道主流的區塊鏈協議大都採用的是單線程串行的執行環境,以Ethereum爲例,其執行環境EVM是一個以交易作爲輸入的狀態機,當出塊節點通過打包區塊完成對交易的排序後,將以該順序通過EVM執行交易,整個過程是完全串行並單線程的,即某個時刻只能有一筆被執行,這樣做的好處是隻要確認了交易順序,執行的結果在廣泛的分佈式集羣中就具有一致性,與此同時由於同時只有一筆交易被串行執行,這就意味着在執行過程中,不可能存在其他交易對某待訪問狀態數據進行修改,這樣就實現了智能合約之間的互操作性。例如我們通過Uniswap使用USDT購買ETH,當該交易被執行時,該交易對中LP的分佈情況即爲一個確定值,這樣就可以通過某些數學模型得出對應的結果,但假設情況不是這樣的,在執行某bonding curve的計算時,有其他LP添加了新的流動性,那麼計算結果將會是一個過時的結果,這顯然是不可接受的。
但是這種架構也有明顯的侷限性,那就是TPS的瓶頸,而這個瓶頸在當前多核處理器下顯得很老舊,就像你用一個最新的PC去玩一些老的電腦遊戲,比如紅警,當作戰單位多到一定數量後,依然會發現卡的不行,這就是軟件架構的問題。
你可能會聽到一些協議已經在關注這個問題,並提出了自己的並行方案,以當前號稱TPS最高的Solana爲例,也具備並行執行的能力。只不過其設計思路與TON不同,在Solana中,其核心思想是將所有交易按照執行依賴關係分爲幾組,不同組之間不共享任何狀態數據。即不存在相同的依賴,這樣不同組內的交易就可以並行執行而不用擔心出現衝突的情況,而對於同組內的交易,則還是沿用傳統的串行方式執行。
而在TON中,其完全捨棄了串行執行的架構,轉而採用了一個專爲並行而生的開發範式,Actor模型來重構執行環境。所謂Actor模型是由Carl Hewitt在1973年首次提出,目的是通過消息傳遞來解決傳統併發程序中共享狀態的複雜性問題。每個Actor都有自己的私有狀態和行爲,且與其他Actor之間不共享任何狀態信息。Actor模型是一種併發計算的計算模型,它通過消息傳遞來實現並行計算。在這個模型中,"Actor"是基本的工作單元,它能夠處理接收的消息、創建新的Actor、發送更多消息、決定如何響應接下來的消息。Actor模型需要具備以下幾個特性:
封裝和獨立性:每個Actor在處理消息時都是完全獨立的,可以並行處理消息而不會互相干擾。
消息傳遞:Actor之間僅通過發送和接收消息進行交互,消息傳遞是異步的。
動態結構:Actor可以在運行時創建更多的Actor,這種動態性使得Actor模型能夠根據需要擴展系統。
TON採用了這個架構,來設計智能合約模型,這就意味着在TON中,每個智能合約都是一個Actor模型,其具備完全獨立的存儲空間。因爲不依賴任何外部數據。除此之外,對同一個智能合約的調用還是按照接收隊列中消息的排序進行執行,因此TON中的交易將可以被高效的並行執行,而不需要擔心衝突問題。
然而這樣的設計方案也帶來了一些全新的影響,對於DApp開發者來說,其習慣的開發範式將被打破,具體如下:
1.智能合約之間的異步調用:在TON的智能合約內部是無法原子性的調用外部合約或訪問外部合約數據的,我們知道在Solidity中,合約A的function1中調用合約B的function2,或者通過合約C的只讀function3訪問某狀態數據,整個過程是原子性的,在一筆交易中被執行,這是一件非常容易的事情,然而在TON中,這將不可能實現,任何與外部智能合約的交互都將通過打包新的交易異步執行,這種由智能合約發起的交易也被稱爲內部消息。且執行過程中無法阻塞以獲得執行結果。
例如我們開發一個DEX,如果採用EVM中常見的範式,通常會有一個統一的router合約用於管理交易路由,而每個Pool都單獨管理某個交易對相關的LP數據,那麼假設當前有兩個池子USDT-DAI和DAI-ETH。當用戶希望通過USDT直接購買ETH,就可以通過router合約在一筆交易中順序請求這兩個池子,完成原子性交易。然而在TON中就沒有這麼容易實現了,需要思考新的開發範式,若仍然複用該該範式的話,那信息流可能是這樣的,這個請求將伴隨一個由用戶發起的external message和三個internal messages完成(注意這是用於說明差異性的,真實的開發中甚至連ERC20的範式也要重新設計)。
2.需要仔細考慮跨合約調用時出現執行錯誤情況的處理流程,爲每個合約間調用設計相應的彈回(bounce)函數。我們知道在主流的EVM中,當交易執行時遇到問題時,整個交易將會被回滾,即被重置到執行最初時的狀態。這在串行單線程模型中是容易理解的。然而在TON中,由於合約間調用採用了異步的方式執行,即使後續某環節出錯,由於前面已經被成功執行的交易已經被執行並確認,這就有可能造成問題。因此TON中設置了一種特殊的消息類型,叫做彈回消息,即當某內部消息觸發的後續執行過程出現錯誤時,被觸發合約可以通過觸發合約預留的彈回函數將觸發合約中的某些狀態重置。
3.在某些複雜情況下,先被接收的交易不一定先被執行完畢,因此不可以預設這種時序關係。在這樣一個異步和並行智能合約調用的系統中,定義處理操作順序可能很難。這就是爲什麼 TON 中的每個消息都有它的邏輯時間Lamport time(後面簡稱 lt)。它用於理解哪個事件引發了另一個以及驗證者首先需要處理什麼。對於一個簡單的模型,先被接收的交易一定先被執行完成。
在這個模型中,A和B分別表示兩個智能合約,則有如果 msg1_lt < msg2_lt,則tx1_lt < tx2_lt的時序關係。
然而在較爲複雜的情況下,這個規則就會被打破。在官方文檔中有這樣的例子,假設我們有三個合約A、B和C。在一筆交易中,A發送兩個內部消息msg1和msg2:一個給B,另一個給C。儘管它們是按確切順序創建的(先msg1,然後是msg2),但我們無法確定msg1 將在msg2之前被處理。這是因爲從 A 到 B 和從 A 到 C 的路由可能在長度和驗證者集中有所不同。如果這些合約位於不同的分片鏈中,其中一條消息可能需要幾個區塊才能到達目標合約。即我們有兩種可能的交易路徑,如圖所示。
4.在TON中,其智能合約的持久化存儲採用了一個以Cell爲單元的有向無環圖作爲數據結構,數據將按照編碼規則緊湊的壓縮爲一個Cell,同時按照有向無環圖的方式向下延伸,這與EVM中狀態數據基於hashmap的結構組織不同,由於數據請求算法的不同,TON中爲不同深度的數據處理設置了不同的Gas價格,越深的Cell數據處理所需要的Gas越高,因此在TON中存在一種DOS攻擊的範式,即某些惡意用戶通過發送大量垃圾消息佔用某個智能合約中所有的淺層Cell,這就意味着誠實用戶的存儲成本將越來越高。而在EVM中,由於hashmap的查詢複雜度爲o(1),因此有着相同的Gas,不會有類似問題。所以TON Dapp開發者應該儘量避免智能合約中出現無界數據類型。當出現無界數據類型時,應通過分片的方式將其打散。
5.還有一些特徵則不那麼特殊了,例如智能合約需要爲存儲支付租金,在TON中智能合約天然是可升級的,以及原生的抽象賬戶功能,即在TON中所有錢包地址均爲智能合約,只是未被初始化等,這些需要開發者小心留意。
以上是這段時間我學習TON相關技術的一些心得,與諸君分享,有寫錯的地方還望大家指正,與此同時,我認爲憑藉着Telegram天量的流量資源,TON生態一定會爲Web3帶來一些全新的應用,有對TON DApp開發感興趣的小夥伴也可以聯繫我,和我們一起討論。
X Links: https://x.com/web3_mario