如何创建支持任意符合条件用户提款的KDA钱包守卫
多用户符合条件提款的钱包守卫实现方案
问题根源
你的代码当前只能支持单个用户+单个NFT组合提款,是因为create-WITHDRAW-guard将特定的recipient和nft-id硬编码进了守卫逻辑里,导致守卫只能验证这一组固定参数。要支持任意数量满足条件的用户,需要让守卫动态验证提款请求的实时条件,而非提前绑定固定参数。
核心修改思路
- 重构能力(Capability)逻辑,让它在提款时动态验证:接收者身份、NFT持有时长、提款金额限额
- 创建通用守卫,不绑定固定用户或NFT,让所有符合条件的请求都能触发验证
修改后的代码示例
;; 假设NFT账本存储了owner-address和transfer-timestamp(持有者获取NFT的时间) (defcap WITHDRAW (recipient:string nft-id:string amount:decimal) ;; 读取NFT的持有者信息和持有起始时间 (with-read mledger nft-id {'owner-address := owner-address, 'transfer-timestamp := transfer-timestamp} ;; 验证接收者是NFT持有者 (enforce (= recipient owner-address) "not the owner of this NFT") ;; 验证持有时长(示例:持有超过30天,按秒计算) (enforce (> (- (time) transfer-timestamp) (* 30 86400)) "NFT holding duration not met") ;; 验证提款金额不超过限额(示例:持有30天以上最多提10 KDA) (enforce (<= amount 10.0) "Withdrawal amount exceeds limit") ) ;; 组合银行借记能力 (compose-capability (BANK_DEBIT)) ) ;; 定义通用的能力检查函数,不绑定固定参数 (defun require-withdraw-permission () ;; 从提款操作的上下文获取参数 (let ((recipient (read-msg "recipient")) (nft-id (read-msg "nft-id")) (amount (read-msg "amount"))) (require-capability (WITHDRAW recipient nft-id amount)) ) ) ;; 创建通用守卫,无需传入固定用户或NFT (defun create-universal-withdraw-guard () (create-user-guard (require-withdraw-permission)) ) ;; 创建带通用守卫的钱包账户 (defun create-shared-wallet (funder:string BANK_KDA_ACCT:string initial-amount:decimal) (coin.transfer-create funder BANK_KDA_ACCT (create-universal-withdraw-guard) initial-amount) ) ;; 提款函数,供符合条件的用户调用 (defun withdraw (recipient:string nft-id:string amount:decimal target-acct:string) ;; 触发守卫的权限检查 (require-withdraw-permission) ;; 执行转账 (coin.transfer BANK_KDA_ACCT target-acct amount) )
关键说明
- 动态参数验证:通过
read-msg从交易上下文获取提款请求的参数,让守卫每次都能验证当前请求的合法性,而非绑定固定值 - 持有时长验证:依赖NFT账本中存储的
transfer-timestamp(持有者获得NFT的时间),结合当前时间计算持有时长,你可以根据需求调整时长阈值 - 金额限额控制:在
WITHDRAW能力中加入金额限制,避免超额提款 - 通用守卫复用:
create-universal-withdraw-guard创建的守卫可以被所有满足NFT持有条件的用户使用,无需为每个用户单独创建守卫
内容的提问来源于stack exchange,提问作者Nexion21
相关产品推荐
相关产品推荐

