Clarity智能合约:如何验证调用公开函数的Principal
Clarity合约中对调用者Principal的身份验证方法
在Clarity合约里,核心是通过内置函数tx-sender获取当前交易发起者的Principal,再与预设的授权地址对比完成验证,以下是具体实现方式:
基础单地址验证
直接将调用者地址与合约中固定的授权地址对比,仅匹配时允许执行逻辑:
(define-contract single-auth-example ;; 预设授权的Principal地址 (define-constant authorized-principal 'ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM) ;; 仅授权地址可调用的公开函数 (define-public (restricted-action) (if (is-eq (tx-sender) authorized-principal) (ok "操作执行成功") (err "未授权:仅指定Principal可调用此函数"))) )
多地址批量验证
如果需要多个地址拥有权限,可将授权地址存入列表,用contains函数判断调用者是否在列表内:
(define-contract multi-auth-example ;; 存储多个授权Principal的列表 (define-constant authorized-principals (list 'ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM 'ST2CY5V39NHDPWSXMW9QDT3HC3GD6Q6XX4CFRK9AG)) (define-public (restricted-action) (if (contains authorized-principals (tx-sender)) (ok "操作执行成功") (err "未授权:仅列表内的Principal可调用此函数"))) )
动态所有者验证
若需要支持所有者地址更新,可使用变量存储当前所有者,仅所有者能修改权限或执行受限操作:
(define-contract owner-auth-example ;; 初始化时将交易发起者设为合约所有者 (define-data-var owner principal tx-sender) ;; 仅当前所有者可更新所有者地址 (define-public (set-new-owner new-owner) (if (is-eq (tx-sender) (var-get owner)) (begin (var-set owner new-owner) (ok "所有者地址更新成功")) (err "未授权:仅当前所有者可修改所有者"))) ;; 仅所有者可执行的受限操作 (define-public (restricted-action) (if (is-eq (tx-sender) (var-get owner)) (ok "操作执行成功") (err "未授权:仅合约所有者可调用此函数"))) )
关键注意点
tx-sender是验证核心,它返回的是发起当前交易的Principal,包括外部用户地址或其他合约地址。- 验证逻辑应放在函数最开头,尽早拦截未授权调用,避免不必要的计算消耗。
- 固定授权地址用
define-constant存储,动态权限用变量(如define-data-var)管理,按需选择。
内容的提问来源于stack exchange,提问作者Bart Brickle
相关产品推荐
相关产品推荐

