FHEVM 用户解密委托怎么做:EOA 直连 ACL 与合约委托两种模式怎么选
FHEVM 用户解密委托怎么做EOA 直连 ACL 与合约委托两种模式怎么选【免费下载链接】fhevmFHEVM, a full-stack framework for integrating Fully Homomorphic Encryption (FHE) with blockchain applications项目地址: https://gitcode.com/GitHub_Trending/fh/fhevm在 FHEVM 里用户解密user decryption是把链上密文在客户端重加密到用户自己的 NaCl 公钥下从而让用户在不上链的情况下读取自己的私密数据如余额、计数器。这套流程由 Relayer 和 KMS 完成前提是 ACL 中已经正确记录了「谁可以在哪个合约的上下文中解密哪个 handle」。当你想让另一个账户比如后端服务、relayer、钱包所有者对应的 EOA替你执行用户解密时就需要用户解密委托user decryption delegation它把(delegator, contractAddress)这对用户解密权限转给(delegate, contractAddress)。FHEVM 对委托入口有明确区分——EOA 和智能合约走的是两条不同的 API选错入口调用会直接 revert。本文基于仓库文档说明两种模式各自怎么调用、怎么选以及如何验证委托是否生效。两种模式delegator 是谁决定你该调哪个 API委托的关键变量是delegator权限的持有者它取决于你调用哪个 API见 docs/solidity-guides/acl/delegation.md调用方使用的 API实际 delegatorACL 眼中的msg.senderEOAExternally Owned Account直接调用 ACL 合约上的IACL.delegateForUserDecryption这个 EOA 自己智能合约在合约函数内部调用FHE.delegateUserDecryptionaddress(this)即调用委托函数的合约由此得到选择规则用户EOA想把「自己的」解密权委托出去→ 必须走 EOA 直连 ACL。文档明确指出FHE.delegateUserDecryption不能用于 EOA 委托自己的权限——EOA 必须直接调用 ACL。合约持有密文 handle想把「该合约名下的」解密权委托出去→ 用FHE.delegateUserDecryption。注意contractAddress参数必须是一个别的合约其 handle 已被允许被当前合约访问。模式一EOA 直接委托给后端服务用户在客户端/脚本中直接对 ACL 合约发起调用docs/solidity-guides/acl/delegation.md 的 Pattern 1import { IACL } from fhevm/solidity/lib/Impl.sol; IACL(aclAddress).delegateForUserDecryption(relayer, vault, expirationDate);三个参数分别是被委托方relayer、密文所在的合约vault、过期时间戳expirationDate。委托生效后relayer 就能对任何带有(EOA, vault)ACL 权限对的 handle 执行用户解密。SDK 侧对应的委托提交实现可参考 delegation.ts其中delegateForUserDecryption通过 viem 的simulateContract 发送交易完成同一笔 ACL 调用。模式二合约委托自己的权限合约可以把自己已被授予的用户解密权限转给 delegate。文档给出的完整示例Aggregator合约import { FHE } from fhevm/solidity/lib/FHE.sol; import { ZamaEthereumConfig } from fhevm/solidity/config/ZamaConfig.sol; contract Aggregator is ZamaEthereumConfig { address public immutable vault; constructor(address vault_) { vault vault_; } function authorizeRelayer(address relayer, uint64 expirationDate) external { FHE.delegateUserDecryption(relayer, vault, expirationDate); } function revokeRelayer(address relayer) external { FHE.revokeUserDecryptionDelegation(relayer, vault); } }FHE.delegateUserDecryption会把调用合约address(this)针对contractAddress的用户解密权限授予delegate。revokeUserDecryptionDelegation用于撤销。常见错误合约里想替 EOA 委托文档特别标注了一个高频踩坑点在合约内部调用FHE.delegateUserDecryption(relayer, address(this), expiration)希望替调用它的用户委托权限——这会一直 revert因为此时msg.sender contractAddress违反下文约束之一。用户的权限只能由用户自己通过模式一EOA 直连 ACL委托。ACL 对委托注册的硬性约束ACL 在注册委托时会强制以下不变量任何一条不满足都会 revert错误名见 docs/solidity-guides/functions.mdcontractAddress ! address(this)—— 违反时 revert 为IACL-SenderCannotBeContractAddress即 EOA 调用方对应的sender 不能是密文所在合约约束。delegate ! address(this)—— revert 为IACL-SenderCannotBeDelegate。delegate ! contractAddress—— revert 为IACL-DelegateCannotBeContractAddress。expirationDate block.timestamp—— revert 为IACL-ExpirationDateInThePast。对每个(delegator, delegate, contractAddress)元组每块最多执行一次委托或撤销one-delegate-or-revoke-per-block。因此传expirationDate时必须用未来时间戳若不需要过期用delegateUserDecryptionWithoutExpiration。连续批量注册/撤销多个委托时要间隔开块不能塞进同一块。e2e 测试中还提到一种线上部署的差异部分 live v0.11 部署的 ACL 要求过期时间距当前超过 1 小时测试通过探测ExpirationDateBeforeOneHour()的 revert 选择器来识别并适配见 delegatedUserDecryption.ts。如果你面向已上线部署先用staticCall探测短过期是否被接受再决定expirationDate取值。完整的 API 清单delegation.md 与 functions.md 汇总的委托相关 API// Granting (caller-contract side) FHE.delegateUserDecryption(delegate, contractAddress, expirationDate); FHE.delegateUserDecryptionWithoutExpiration(delegate, contractAddress); FHE.delegateUserDecryptions(delegate, contractAddresses, expirationDate); // batch FHE.delegateUserDecryptionsWithoutExpiration(delegate, contractAddresses); // batch // Revoking FHE.revokeUserDecryptionDelegation(delegate, contractAddress); FHE.revokeUserDecryptionDelegations(delegate, contractAddresses); // batch // Querying FHE.isDelegatedForUserDecryption(delegator, delegate, contractAddress, handle); // active for handle? FHE.getDelegatedUserDecryptionExpirationDate(delegator, delegate, contractAddress); // 0 none, max permanent FHE.isUserDecryptable(handle, user, contractAddress); // raw ACL check, ignores delegation注意区分最后两个查询isDelegatedForUserDecryption检查委托链路对该 handle 是否生效isUserDecryptable只做原始 ACL 检查用户和合约都必须持有该 handle 的持久权限不考虑委托。执行与验证委托后如何确认生效端到端的验证路径在 e2e 套件 delegatedUserDecryption.ts 中可以直接照做主路径如下发起委托交易并等待回执。例如合约所有者让 Bob 的 EOA 获得解密智能钱包余额的权限const expirationTimestamp Math.floor(Date.now() / 1000) ONE_DAY_SECONDS; const delegateTx await smartWallet .connect(signers.bob) .delegateUserDecryption(signers.bob.address, tokenAddress, expirationTimestamp); await delegateTx.wait();等待 coprocessor 吸收 ACL 变更。e2e 测试在委托/撤销交易之后等待约 15 个 host-chain 区块PROPAGATION_BLOCKS 15再尝试解密。如果你刚提交委托就立刻解密失败先确认 ACL 变更是否已经被 coprocessor 处理而不是急着判定委托失败。用委托方的签名调用 SDK 的委托用户解密成功即证明链路打通const decryptedBalance await instances.bob.delegatedUserDecryptSingleHandle({ handle: balanceHandle, contractAddress: tokenAddress, delegatorAddress: smartWalletAddress, // 权限持有者合约/EOA不是请求方 signer: signers.bob, // delegate 的签名者 });成功判据返回的明文与密文实际值一致e2e 中通过对照解密后的期望值断言。delegatorAddress必须填权限持有者——合约场景就是持有权的合约地址EOA 场景就是发起delegateForUserDecryption的那个 EOA。链上查询兜底用FHE.getDelegatedUserDecryptionExpirationDate(delegator, delegate, contractAddress)确认记录存在且未过期返回0表示不存在max表示永久或直接用FHE.isDelegatedForUserDecryption(delegator, delegate, contractAddress, handle)检查某个具体 handle。失败场景与错误含义e2e 套件覆盖了四类会被 ACL/relayer 拒绝的情况可用于排查「委托了却解不了密」委托已被撤销先revokeUserDecryptionDelegation并等待传播再用原 delegate 调用delegatedUserDecryptSingleHandle会失败错误信息对应 SDK 的getDelegatedUserDecryptErrorMessage的revocation类型。委托不存在从未注册过委托的账户调用报delegation-does-not-exist类错误。委托给了错误的合约contractAddress与密文实际所在合约不一致报contract-unauthorized类错误。委托已过期expirationDate过去后同样被拒错误形态与错误合约场景一致contract-unauthorized类。另有一条硬边界来自 ACL 本身的语义同样由 e2e 用例验证通配/按合约委托都不绕过 ownership——delegator 必须对该 handle 有 ACL 权限密文所在合约也必须有权限且委托不能传递性地二次转授。选型小结你的情况正确入口要点用户自己的 EOA 想把解密权交给后端/relayerIACL(aclAddress).delegateForUserDecryption(...)EOA 亲自签名FHE.delegateUserDecryption帮不了你合约持有 handle想让 relayer 代解合约内FHE.delegateUserDecryption(delegate, vault, expiration)vault必须是别的合约撤销用FHE.revokeUserDecryptionDelegation需要多个合约一次性委托FHE.delegateUserDecryptions/ 批量撤销每个元组每块一次批量时注意跨块只想读状态getDelegatedUserDecryptionExpirationDate/isDelegatedForUserDecryptionisUserDecryptable不反映委托别用它验证委托如果委托后解密仍失败按 e2e 的失败矩阵依次核对委托记录是否存在链上查询→ 是否已过期/被撤销 →contractAddress是否与密文所在合约一致 → ACL 变更是否已传播等待约 15 个区块。更多委托 API 的参数细节见 User decryption delegation委托与 ACL 权限授予FHE.allow的配合关系见 Access Control List 概览 与 用户解密。【免费下载链接】fhevmFHEVM, a full-stack framework for integrating Fully Homomorphic Encryption (FHE) with blockchain applications项目地址: https://gitcode.com/GitHub_Trending/fh/fhevm创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考