通用执行器账户(UEA)

  • pushchain
  • 发布于 2026-03-16 11:46
  • 阅读 7

Universal Executor Accounts (UEA) 是 Push Chain 上的一种确定性智能合约账户,用于代表外部链用户与 Push 应用交互,无需用户拥有 Push 原生钱包。

合约位置


什么是 UEA?

通用执行账户(Universal Executor Account,简称 UEA)是一个部署在 Push Chain 上的确定性智能合约账户,它代表来自外部链的用户,并允许该用户在无需“原生在 Push 上”的情况下与 Push 应用交互。UEA 并非要求用户创建 Push 原生钱包/账户,而是将每个外部身份映射到一个 UEA,并将该 UEA 视为用户在 Push 执行环境中的链上身份。

目前有两种 UEA 实现:

  • UEA_EVM:用于基于 EVM 的链(例如以太坊)。使用 ECDSA 签名(EIP-712 风格的有效载荷哈希 + ecrecover)验证所有权。
  • UEA_SVM:用于基于 Solana/SVM 的链。使用 Ed25519 签名(通过地址为 0x00000000000000000000000000000000000000ca 的验证器预编译进行验证)验证所有权。

在两种情况下,UEA 都成为 Push 上的实际调用者:当执行有效载荷时,应用会看到 msg.sender == UEA,从而为用户在 Push 上提供一个稳定的身份,该身份与其外部链密钥绑定。


使用 UEA 的入向流程(Ethereum → Push Chain)

示例:Bob 是一名以太坊用户,想要存入资金并执行一次 Push 链调用。

  1. Bob 在以太坊上提交入向请求

    • Bob 与以太坊侧的通用网关(Universal Gateway)交互,发送资金及一个编码后的有效载荷(目标地址 + calldata),这些数据将发往 Push Chain。
  2. 以太坊侧网关锁定/托管资金并发出事件

    • 网关锁定资产并发出事件,该事件包含代币、金额、目标详情以及编码后的调用意图。
  3. 验证者/中继器观察该事件并最终将其提交至 Push

    • Push 的链下验证层(通用验证者/中继器/TSS,具体取决于路由)确认事件,并准备在 Push 上执行入向操作。
  4. Push 将包装后的表示(pTokens)铸造到 Bob 的 UEA

    • 在 Push Chain 上,入向管道将相应的 pToken(例如 DAI → pDAI)铸造到 Bob 的 UEA。
  5. Push 确保 Bob 的 UEA 存在

    • 如果 Bob 是首次使用,Push 通过 UEAFactory.deployUEA(UniversalAccountId) 确定性地部署他的 UEA。
  6. Push 通过 Bob 的 UEA 执行入向有效载荷

    • 入向管道调用 UEA.executeUniversalTx(payload, signature)。如果调用者是 UNIVERSAL_EXECUTOR_MODULE(地址 0x14191Ea54B4c176fCf86f51b0FAc7CB1E71Df7d7),则跳过签名验证。否则,UEA 在执行前验证签名。目标 Push 合约被调用,就像 Bob 是执行者一样——即目标合约看到 msg.sender == Bob 的 UEA
  7. 目标合约运行并在 Bob 的 UEA 身份下更新状态

    • 任何余额、持仓、状态(质押、借贷、交换等)都会以 UEA 作为 Bob 在 Push 上的身份进行记录。
以太坊(外部链)                           Push Chain
──────────────────────────                         ─────────────────────────
Bob(EOA / 智能账户)
   |
   | 1) 将资金 + 有效载荷存入 UniversalGateway (ETH)
   v
UniversalGateway (ETH)
   |
   | 2) 锁定/托管资金 + 发出事件(代币、金额、有效载荷、原始身份)
   v
验证者 / 中继器(链下)
   |
   | 3) 验证事件并向 Push 提交入向执行
   v
Push 入向管道
   |
   | 4) 如果需要,部署 UEA(通过 UEAFactory)
   | 5) 将 pTokens 铸造到 Bob 的 UEA
   | 6) 调用 UEA.executeUniversalTx(...)
   v
Bob 的 UEA(Push Chain)
   |
   | 7) 在 Push 上执行目标合约调用
   v
目标应用合约(Push)
   |
   | msg.sender == Bob 的 UEA
   v
更新状态 / 执行操作

UEA 的确定性创建

UEA 通过 UEAFactory 使用确定性部署创建,使得用户的 UEA 地址可预测且稳定。工厂从用户的 UniversalAccountId(链命名空间 + 链 ID + 所有者密钥)推导出一个盐值,并使用 OpenZeppelin 的 Clones.cloneDeterministic 在确定性地址上部署每个用户专用的 UEAProxy。然后初始化代理,使其指向正确的实现:

  • UEA_EVM 用于 EVM 来源的用户
  • UEA_SVM 用于 Solana 来源的用户

部署流程:

  1. UEAFactory 使用 cloneDeterministic(salt) 克隆 UEAProxy 模板,其中 salt = keccak256(abi.encode(_id.chainNamespace, _id.chainId, _id.owner))
  2. UEAFactory 调用 UEAProxy.initializeUEA(UEA_IMPLEMENTATION),根据链的 VM 类型设置实现。
  3. UEAFactory 通过代理调用 UEA.initialize(UniversalAccountId, factory)

这保证:一个外部身份 ↔ 一个稳定的 UEA 在 Push 上。


控制模型:只有所有者才能通过 UEA 执行

UEA 由外部用户的密钥控制:

  • 对于 UEA_EVM:UEA 验证一个 ECDSA 签名,该签名基于执行请求的 EIP-712 风格有效载荷哈希(使用 domainSeparator()getUniversalPayloadHash(payload) 生成)。签名通过 ECDSA.recover() 恢复,并与 address(bytes20(universalAccountId.owner)) 进行比较。
  • 对于 UEA_SVM:UEA 通过地址为 VERIFIER_PRECOMPILE 的验证器预编译验证 Ed25519 签名。

如果签名无效,调用会回滚。这确保第三方无法通过他人的 UEA 执行任意操作。

此外,一个受信任的系统组件(UNIVERSAL_EXECUTOR_MODULE,地址为 0x14191Ea54B4c176fCf86f51b0FAc7CB1E71Df7d7)被允许在无需签名验证的情况下调用 executeUniversalTx,因为入向执行管道已在协议层通过了身份验证。

有效载荷执行模式:

  • 单次调用:直接对目标合约执行
  • 多重调用(Multicall):在一个交易中批量执行多个调用(通过 MULTICALL_SELECTOR 前缀标识)
  • 迁移:升级 UEA 实现逻辑(通过 MIGRATION_SELECTOR 前缀标识,不能作为多重调用中的子调用)

有效载荷执行

UEA_EVMUEA_SVM 都使用共享的 _handleExecution 调度器,它读取 payload.data 的前 4 个字节以确定要使用的执行模式:

  • MULTICALL_SELECTORbytes4(keccak256("UEA_MULTICALL")))→ _handleMulticall:解码一个 Multicall[] 数组,并依次遍历每个 {to, value, data} 条目,按顺序调用每个目标。迁移不能作为多重调用中的子调用包含在内。
  • MIGRATION_SELECTORbytes4(keccak256("UEA_MIGRATION")))→ _handleMigration:必须是一个独立的有效载荷(不能嵌套在多重调用中)。要求 payload.to == address(this)payload.value == 0。通过 delegatecall 调用 UEAFactory.UEA_MIGRATION_CONTRACT(),分别调用 migrateUEAEVM()(用于 EVM UEA)或 migrateUEASVM()(用于 SVM UEA)。
  • 其他情况_handleSingleCall:直接对 payload.to 执行 call{value}(data)
executeUniversalTx(payload, sig)
        │
        ├─ [UE 模块调用者] ──────────────────────────────────┐
        │                                                       │
        └─ [验证 ECDSA / Ed25519] ────────────────────────── │
                                                                │
                                           _handleExecution(payload)
                                                   │
                            ┌──────────────────────┼──────────────────────┐
                            │                      │                      │
                     MULTICALL_SELECTOR   MIGRATION_SELECTOR      (其他任何情况)
                            │                      │                      │
                    _handleMulticall()    _handleMigration()    _handleSingleCall()
                   (批量调用)             (通过 delegatecall      (对 payload.to 的单次调用)
                                           调用迁移合约)

外部依赖

UEA_EVM

  • OZ ECDSA 库(不可变)— 用于 EVM 密钥的签名恢复
  • ueaFactory.UEA_MIGRATION_CONTRACT()(工厂管理员可变)— 迁移目标;工厂管理员控制哪个迁移合约处于活动状态
  • 多重调用/单次调用中的目标合约— 不可信、任意;UEA 不对目标行为做任何假设

UEA_SVM

  • 地址为 0x00000000000000000000000000000000000000ca 的 Ed25519 预编译 — Push Chain 特有的 Cosmos EVM 预编译,用于 Ed25519 签名验证。硬编码;在非 Push 分叉上不可用时无备用方案。
  • ueaFactory.UEA_MIGRATION_CONTRACT()(工厂管理员可变)— 迁移目标
  • 目标合约(不可信、任意)

UEA 迁移概述(升级 UEA 逻辑)

UEA 使用代理模式(UEAProxy),代理将执行委托给存储在固定存储槽(UEA_LOGIC_SLOT)中的 UEA 实现。迁移通过更新此实现指针到新版本来完成。

高层流程:

  1. 部署新的 UEA 实现(例如 UEA_EVM v2 / UEA_SVM v2)。
  2. 部署新的 UEAMigration 合约,配置 EVM 和 SVM 的新实现地址。
  3. 通过 UEAFactory.setUEAMigrationContract(migrationAddress) 将工厂更新为指向最新的迁移合约。
  4. 用户通过 UEA 执行路径触发迁移:有效载荷数据必须以 MIGRATION_SELECTOR 开头,且 payload.to == address(this)。这是一个专用的执行模式,而非普通调用。
  5. UEA 通过 delegatecall 委托给迁移合约,迁移合约更新代理的实现槽(UEA_LOGIC_SLOT)为新的逻辑合约。对于 EVM UEA,调用 UEAMigration.migrateUEAEVM();对于 SVM UEA,调用 UEAMigration.migrateUEASVM()

结果:UEA 保持相同地址(身份),但运行新的逻辑。

有关完整的分步流程及图表,请参见 docs/CEA_UEA_MIGRATION_FLOW.md

  • 原文链接: github.com/pushchain/pus...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
pushchain
pushchain
江湖只有他的大名,没有他的介绍。