You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

跨模块通过install-capability安装managed capability是否可行

问题

是否可在不对交易数据中的capability进行签名的前提下,在定义某managed capability的模块外部安装该能力?

场景说明

需要在自定义模块实现的函数中调用coin.transfer-create,完成模块控制账户向用户账户的转账操作,该函数受coin.TRANSFER managed capability的权限保护。

  • 若交易签名时在capabilities列表中声明coin.TRANSFER capability,即可正常调用内部会触发coin.transfer-create的自定义模块函数。
  • 目标实现效果:任意用户账户都可向模块账户申领KDA,无需用户在交易的capabilities列表中提供coin.TRANSFER capability(用户并不掌握模块账户的私钥,该合约仅部署用于测试网)。

测试时使用的实现逻辑如下,在REPL环境运行触发keyset failure报错:

(defun my-fn (user-account:string amount:decimal)
  ; install the capability, without relying on it being in the capabilities list
  (install-capability (coin.TRANSFER "contract-account" user-account amount))
  ; grant the capability
  (with-capability (coin.TRANSFER "contract-account" user-account amount)
    <execute transfer>))
解答

不可以在定义managed capability的模块外部,通过install-capability接口安装该能力绕过签名校验,你遇到的keyset failure是合约权限机制的正常表现:

  • install-capability仅对定义目标capability的模块内部调用生效,外部模块调用该接口无法获得对应capability的授予权限,该设计的核心目的就是防止跨模块越权绕过内置的权限校验逻辑。
  • coin.TRANSFER是coin模块定义的托管capability,默认会校验转出账户的守卫权限,你在自定义模块中直接调用install-capability安装coin.TRANSFER属于跨模块无效调用,执行到with-capability逻辑时依然会触发转出账户的keyset校验,没有对应签名就会抛出错误。

要实现测试网任意用户无签名申领KDA的领水功能,不需要强行跨模块安装capability,正确实现路径如下:

  1. 不要使用普通keyset守卫创建合约控制的账户,改用模块principal作为账户守卫,即通过(create-principal (my-contract.module-hash))生成模块专属principal作为账户的守卫规则。
  2. 当转出账户的守卫是你的自定义模块时,只要转账逻辑在你的自定义模块内部执行,coin模块会自动认可模块守卫的权限,不需要交易签名额外声明coin.TRANSFER capability,也不需要用户持有模块账户私钥,任意用户调用你公开的申领函数即可完成转账。

内容的提问来源于stack exchange,提问作者trh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 06:15:39