Gas Station处理cont类型交易时如何校验模块名称?
问题:如何为Cont类型交易实现Gas Station的模块名称校验
我实现了一个Gas Station,当尝试用它为cont类型交易支付Gas时,系统抛出"Inside an exec"错误。当前的GAS_PAYER能力代码仅支持exec类型交易,且仅能校验该类型交易是否由指定合约发起:
(defcap GAS_PAYER:bool ( user:string limit:integer price:decimal ) (enforce (= "exec" (at "tx-type" (read-msg))) "Inside an exec") (enforce (= 1 (length (at "exec-code" (read-msg)))) "Tx of only one pact function") (enforce (= "(free.anedak." (take 13 (at 0 (at "exec-code" (read-msg))))) "only free.anedak smart contract") (compose-capability (ALLOW_GAS)) )
目前的校验逻辑依赖exec类型交易的exec-code字段,但cont类型交易没有这个字段,现有的cont类型Gas支付示例也未包含模块名称校验逻辑。需要找到可行方案实现cont交易的模块校验,避免Gas Station被滥用。
解决方案
修改GAS_PAYER能力,区分处理exec和cont两种交易类型,利用Pact内置的read-cont函数获取cont交易的模块归属信息:
(defcap GAS_PAYER:bool ( user:string limit:integer price:decimal ) (let* ((tx-type (at "tx-type" (read-msg))) (valid-module? (case tx-type ("exec" ;; 保留原有的exec交易校验逻辑 (and (= 1 (length (at "exec-code" (read-msg)))) (= "(free.anedak." (take 13 (at 0 (at "exec-code" (read-msg)))))) ("cont" ;; 读取cont的元数据,校验所属模块 (let* ((cont-id (at "cont-id" (read-msg))) (cont-meta (read-cont cont-id))) (= "free.anedak" (at "module" cont-meta)))) ;; 其他交易类型直接判定为无效 (false)))) (enforce valid-module? "Only transactions from free.anedak contract are allowed") (compose-capability (ALLOW_GAS))) )
方案说明
- 交易类型区分:通过
(at "tx-type" (read-msg))获取当前交易类型,分别处理exec和cont交易 - exec交易校验:保留原有的逻辑,确保仅执行单个
free.anedak模块的函数 - cont交易校验:
- 通过
(at "cont-id" (read-msg))获取cont交易的ID - 调用
read-cont读取该cont的链上元数据,其中module字段记录了创建该cont的模块名称 - 直接校验模块名称是否为目标模块
free.anedak
- 通过
- 非法类型拦截:非exec/cont类型的交易直接被拒绝
这个方案利用了continuation的元数据特性,确保只有指定模块创建的cont交易才能使用你的Gas Station,有效防止滥用。
内容的提问来源于stack exchange,提问作者0xarvind
相关产品推荐
相关产品推荐

