Minimal Modular Smart Account

ERC-7579 定義了最低限度的模組話合約簽包實作,與 ERC-6900 相比簡化了大量的邏輯,以保證 interoperability 和開發門檻。

Module Spec

ERC-7579 定義了幾個不同類型的模組,未來也可以規劃其他 ERC 進行擴充

TypeIDDescription
Validation1驗證模組,可以實作 key abstraction 或是 ERC-4337 UserOps 的驗證
Execution2執行模組,可以擴充 Execution 的功能,實作 Time Lock 或是 Multisig
Fallback3處理 fallback 函式的模組
Hooks4可以在驗證或是執行的函式前後,掛上自定義的邏輯

所有的模組都必須實作 IERC7579Module interface

  • onInstall 當模組被 Account 安裝時需要執行的函式
  • onUninstall 當模組被 Account 解除安裝時需要執行的函式
  • isModuleType 這個模組是哪個 type 的模組,需要注意的是一個模組可以是複數個 type 的模組,也就是說一個模組可以同時實作 Validation 和 Execution 的邏輯,isModuleType 傳入 1 或是 2 都會回傳 true
interface IERC7579Module {
 
    function onInstall(bytes calldata data) external;
 
    function onUninstall(bytes calldata data) external;
 
    function isModuleType(uint256 moduleTypeId) external view returns(bool);
}

Validation Module

驗證模組還需實作 IERC7579Validator interface

  • validateUserOp 滿足 ERC-4337 驗證 UserOps
  • isValidSignatureWithSender 以 ERC-1271 驗證簽名
interface IERC7579Validator is IERC7579Module {
 
    function validateUserOp(
        PackedUserOperation calldata userOp,
        bytes32 userOpHash
    ) external returns (uint256);
 
    function isValidSignatureWithSender(
        address sender,
        bytes32 hash,
        bytes calldata signature
    ) external view returns (bytes4);
}

Hook Module

Hook 模組還需實作 IERC7579Hook interface

  • preCheck 在 Account Execution 相關的函式之前執行
  • postCheck 在 Account Execution 相關的函式之後執行
interface IERC7579Hook is IERC7579Module {
 
    function preCheck(
        address msgSender,
        uint256 value,
        bytes calldata msgData
    ) external returns (bytes memory hookData);
 
    function postCheck(bytes calldata hookData) external;
}

Account Spec

Execution

一個 Account 需要實作 IERC7579Execution interface 以執行交易

  • execute 是處理交易最基本的函式
  • executeFromExecutor 用於給 Execution Module 呼叫的函式
  • executeUserOp 用於給 ERC-4337 EntryPoint 執行 UserOps 的函式 (optional)

這裡 bytes32 mode 是一些執行資訊的 encode,其 format 如下:

CallTypeExecTypeUnusedModeSelectorModePayload
1 byte1 byte4 bytes4 bytes22 bytes

比較重要的是 CallType,定義了函式呼叫是以 staticcall, single-call, batch-call 還是 delegatecall 來執行。ExecType 則定義了函式呼叫後,遇到錯誤的處理方式

interface IERC7579Execution {
    function execute(bytes32 mode, bytes calldata executionCalldata) external;
 
    function executeFromExecutor(bytes32 mode, bytes calldata executionCalldata)
        external
        returns (bytes[] memory returnData);
 
    // optional
    function executeUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash) external;
}

Account Info

一個 Account 需要實作 IERC7579AccountConfig interface 以提供 account 相關的資訊

  • accountId 回傳 account ID
  • supportsExecutionMode 檢查 account 是否支援 execution mode
  • supportsModule 檢查 account 是否支援某個 module type ID
interface IERC7579AccountConfig {
 
    function accountId() external view returns (string memory accountImplementationId);
 
    function supportsExecutionMode(bytes32 encodedMode) external view returns (bool);
 
    function supportsModule(uint256 moduleTypeId) external view returns (bool);
}

Module Management

一個 ERC-7579 Account 需要實作 IERC7579ModuleConfig interface 用以管理模組

  • installModule 安裝一個模組
  • uninstallModule 解除安裝一個模組
  • isModuleInstalled 某個模組是否已被安裝
interface IERC7579ModuleConfig {
    event ModuleInstalled(uint256 moduleTypeId, address module);
    event ModuleUninstalled(uint256 moduleTypeId, address module);
 
    function installModule(uint256 moduleTypeId, address module, bytes calldata initData) external;
 
    function uninstallModule(uint256 moduleTypeId, address module, bytes calldata deInitData) external;
 
    function isModuleInstalled(
        uint256 moduleTypeId,
        address module,
        bytes calldata additionalContext
    ) external view returns (bool);
}

Conclusion

ERC-7579 Account 具體的 execution flow 簡略如下,可以和 ERC-4337 整合,可以以 EOA 直接操作 Account,也可以安裝第三方模組擴充 Account 的功能。整合上的 interface 也十分單純,方便錢包商和獨立開發者做各種功能的延伸。

Reference