合約解析

DiamondApp

1. /contracts/Diamond.sol 核心設計

abstract contract Diamond is IDiamond, Proxy, DiamondCutBase, DiamondLoupeBase, Initializable {
 constructor(InitParams memory initDiamondCut) initializer {
 _diamondCut(initDiamondCut.baseFacets, initDiamondCut.init, initDiamondCut.initData);
 }

 function _implementation() internal view override returns (address facet) {
 facet = _facetAddress(msg.sig);
 if (facet == address(0)) revert Diamond_UnsupportedFunction();
 }
}

核心設計要點

  • 繼承結構:組合了Proxy(代理轉發)、DiamondCutBase(切面管理)、DiamondLoupeBase(切面資訊查詢)和Initializable(可初始化)等核心功能
  • 建構子:接受InitParams參數並透過_diamondCut函數初始化基礎切面
  • 代理邏輯:重寫_implementation()函數,根據函數簽章動態路由到對應切面(facet)
  • 抽象合約:自身不實現具體業務邏輯,僅提供Diamond模式的核心框架

2. /contracts/apps/TokenUnlocker/App.sol 設計

contract TokenUnlockerApp is Diamond {
 constructor(InitParams memory initDiamondCut) Diamond(initDiamondCut) {}
}

3. /contracts/apps/TuringMarket/App.sol 設計

contract TuringMarketApp is Diamond {
 constructor(InitParams memory initDiamondCut) Diamond(initDiamondCut) {}
}

應用合約設計要點

  • 輕量級實作:僅繼承Diamond合約並傳遞初始化參數
  • 應用隔離:每個應用程式(TokenUnlocker和TuringMarket)有獨立的Diamond實例
  • 建構子轉送:將InitParams直接傳遞給父合約,保持初始化邏輯統一

整體架構設計亮點

  1. 模組化設計
  • 透過Diamond模式將功能拆分為獨立切面(facets)
  • 應用層與核心框架分離,方便維護與升級
  1. 可擴展性
  • 支援動態新增/取代/刪除功能切面
  • 新應用程式只需繼承Diamond合約即可快速構建
  1. 升級安全
  • 使用Initializable確保初始化邏輯只執行一次
  • 代理模式保證位址不變的情況下實現功能升級
  1. 路由機制
  • 基於函數簽章的動態路由,高效率轉送調用
  • 不存在的函數會觸發Diamond_UnsupportedFunction異常

設計模式應用

  • 代理模式:透過Proxy實現功能與資料分離
  • 工廠模式InitParams參數結構標準化初始化流程
  • 組合模式:透過多重繼承組合不同功能模組
  • 模板方法模式Diamond合約定義框架,具體應用繼承並擴展

這種設計符合EIP-2535標準,為複雜DApp提供了模組化、可升級的架構基礎,同時保持了程式碼的簡潔性和可維護性。