一般來說,遊戲是基於循環的系統(loop-based)。遊戲循環是一個不斷重複的過程,通常包含處理用戶輸入、更新遊戲狀態和渲染遊戲世界這幾個步驟。這個循環在遊戲運行期間持續進行,通常每秒運行數十次到數百次,以保持遊戲世界的流暢性。
然而,區塊鏈的架構是基於推送(push-based)的。區塊鍊是一個分佈式的數據庫,它通過網絡中的節點共享和存儲信息。當一個節點產生一個新的交易(如轉賬、合約調用等)時,這個交易會被推送到網絡中,其他的節點收到這個交易後會驗證它並將它添加到區塊鏈中。這是一個被動的過程,節點不會主動去查找新的交易,而是等待網絡中的其他節點發送新的交易。因此,區塊鏈的架構被稱為是基於推送的。
因此,在全鏈遊戲中實現一個帶有時鐘週期的循環系統就變得非常重要。畢竟在所謂的“自治世界”中,我們都希望一些NPC或者虛擬環境是可以自動的隨時間演化,而不是跟隨被推送到區塊鏈的交易輸入被動演化。
@therealbytes 開發了一個基於OP Stack的概念驗證型滴答鏈(帶有時鐘週期的鏈),它運行了一個自動滴答的康威生命遊戲實現,我們下面來了解他到底是如何實現的。
為保持翻譯的簡單,我們把tick 直譯成“滴答”,意思就是“循環時鐘週期”。
Ticking-Optimism 是一個基於Optimism Bedrock rollup架構的“滴答區塊鏈”的概念驗證實現。
在滴答鏈中,有一個特殊的智能合約叫做“滴答合約”,每個區塊都會被協議自動調用。這允許其他智能合約在特定的時間或間隔自動觸發,無需用戶發送交易。
如何實現
Optimism的新的模塊化rollup架構,Optimism Bedrock,引入了一種新的交易類型叫做“存款交易”(Deposit Transaction)。與常規交易不同,存款交易:
- 來自Layer 1 的區塊。
- 不需要簽名驗證。
- 在L1上購買L2的gas,所以L2的gas是不可退還的。
在原始的Bedrock中,存款交易用於兩件事:
- 執行直接發送到L1的交易。
- 在每個區塊中為預先部署的L2合約設置L1屬性(編號、時間戳、哈希等)。
在後一種情況下,交易由rollup節點創建。它不支付gas,使用的gas不會從gas池中扣除。
Ticking-Optimism修改了rollup節點,也創建了一個“滴答交易”(tick transaction),工作方式相同,但不是設置L1屬性,而是在預先部署到地址0x42000000000000000000000000000000000000A0的合約中調用tick()函數。這個合約可以通過設置其目標變量來調用另一個合約。
動機
為了說明滴答鏈的威力,想像一個區塊鏈上的遊戲,其中多個NPC(非玩家角色)在地圖上移動。沒有滴答鏈,我們有兩種主要的設計方法:
-懶更新( Lazy updating ) 。在客戶端,NPC似乎連續移動,但它們的位置只有在用戶發送與它們互動的交易時才在鏈上更新。然後,合約根據其最後的鏈上更新和自那時起經過的區塊數計算NPC的新位置。
-手動滴答( Manual ticking ) 。我們定義一個更新函數,設置地圖上每個NPC的位置,並有一個外部帳戶定期調用它。
使用滴答鏈,解決方案與手動滴答相似,但滴答合約會自動調用更新函數,而不是手動調用。
使用滴答鏈的“自動滴答”而不是手動滴答的優點是:
- 更新由協議保證。
- 更新將在塊中的所有交易之前執行,不能被前置,因為它是協議本身的一部分。
- 更新交易不參與常規的gas市場。
然而,自動滴答需要一個定制的區塊鏈。如果更新率相同,手動和自動滴答對節點的計算資源需求相同。另一方面,懶更新通常更便宜,因為鏈上更新更小、更少。
此外,隨著需要更新的狀態增長,滴答交易的計算成本也增加。這給開發者帶來了額外的壓力,要求他們設計他們的應用程序,確保成本永遠不會超過鏈所能支持的。
儘管有這些巨大的缺點,自動滴答對於某些類型的應用程序比懶更新更合適。
1. 狀態始終明確地在鏈上並且是最新的
滴答使智能合約能夠以恆定的成本訪問一個動態狀態,該狀態使用開放形式的表達式更新。
狀態(在上面的例子中,是NPC的位置)總是可以在鏈上以恆定的、相對較低的gas成本讀取。但是計算當前狀態的成本會隨著自上次更新以來的區塊數增加時,gas成本增加的也比較多。
如果我們正在更新一個以恆定速度移動的實體的位置,我們可以從其最後設置的位置和自更新以來的區塊數計算出它應該在任何給定的區塊中的位置。這個操作的成本不會隨著更新之間的區塊數增長。
另一方面,如果我們更新的狀態是像康威的生命遊戲(或三體重力模擬)這樣的東西,更新的成本與自上次更新以來的步驟數成線性增長。這是一個問題,因為它可以增長到超過用戶願意支付的或鏈所能支持的。
2. 客戶端的作用不同
使用懶更新,更新邏輯需要在智能合約和客戶端中都實現。使用滴答,只需要在區塊鏈上實現,客戶端可以簡單地對鏈上事件做出反應。
3. 代碼更簡單,更容易審核
懶更新使開發者將他們的更新邏輯分散在許多函數和智能合約中,每個函數只在執行某些交易時觸發。相比之下,滴答方法只需要一個保證定期觸發的更新函數。後者使得更容易維護狀態的一致性和完整性。
此外,每次添加一個新的懶更新狀態(例如,一個新類型的NPC)時,所有更新函數可能都需要修改以考慮它。這使得代碼庫更複雜,更容易出問題。
4. 用戶不支付更新成本
懶更新的成本通常變化很大,用戶可以製定他們的交易,使大部分更新的負擔落在其他人身上。使用滴答,所有操作的成本都相對穩定,不容易受到MEV攻擊。
康威的生命遊戲演示
我構建了一個滴答鏈的演示,運行一個交互式版本的康威的生命遊戲。鏈已經修改,包括在執行引擎中的細胞自動機邏輯,使其更高效,允許比作為智能合約字節碼實現的更大的遊戲板。
演示的源代碼: https://github.com/therealbytes/ticking-conway
演示視頻: https://www.youtube.com/watch?v=za12aa5FS6E&list=PL_97Yn8lCzTI_P_4vO1HEXA9k6gF6lawF&index=11