news 2026/9/24 18:23:00

EOSIO cleos 解除权限链接实战:用 `set action permission ... NULL` 移除动作的权限绑定(unlinkauth)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
EOSIO cleos 解除权限链接实战:用 `set action permission ... NULL` 移除动作的权限绑定(unlinkauth)
  • 区块链

【免费下载链接】eos

An open source smart contract platform

项目地址:https://gitcode.com/gh_mirrors/eo/eos
点击查看免费下载

导读

在 EOSIO 区块链上,权限链接(permission link)机制允许账户为某个智能合约的具体 action 单独指定一个最低授权权限,从而把合约调用的鉴权从默认的active/owner权限中剥离出来。本文以 eos 仓库中的官方操作指南为基础,讲解如何通过cleos set action permission命令配合关键字NULL解除(unlink)一个已链接的权限级别,并深入仓库源码,揭示该命令在cleos客户端、链上unlinkauth原生动作与authorization_manager校验逻辑中的完整执行链路。读完本文,你将能独立完成"为指定合约动作解除权限绑定、恢复默认授权行为"的完整操作,并理解解除操作的底层原理与失败场景。

前置条件(Before you begin)

在动手解除权限链接之前,需要满足以下条件:

  • 安装当前受支持的cleos版本cleos随 EOSIO 软件一同分发,安装 EOSIO 即会同时安装cleoskeosd两个命令行工具,安装指引见 docs/00_install/index.md。
  • 理解以下基础概念
    • 账户(Account):EOSIO 上的身份实体,所有权限与合约动作都挂载在账户之下;
    • 权限级别(Permission Level):账户内部的授权层级,最常用的是owneractive,也可以自定义子权限(如customp);
    • 动作(Action):智能合约暴露的可调用操作,例如转账合约的transfer动作。

核心概念:什么是"解除权限链接"

EOSIO 的权限链接是一张"动作 → 最低权限"的映射表。当你执行

cleos set action permission alice hodlcontract transfer customp -p alice@active

时,链上实际产生的是一个eosio::linkauth动作,其数据为{"account":"alice","code":"hodlcontract","type":"transfer","requirement":"customp"},含义是:只有持有不低于customp权限的签名,才被允许以账户alice的身份调用hodlcontract合约的transfer动作

"解除权限链接"就是把这张映射删除:此后该动作不再有专门的最低权限要求,恢复为 EOSIO 的默认行为——即由调用时使用的权限直接决定能否执行(通常对应账户的active权限)。

与之对应的操作是建立权限链接,完整的操作指南见 docs/02_cleos/02_how-to-guides/how-to-link-permission.md。链接与解除使用同一条命令,区别仅在于最后一个位置参数是权限名还是NULL

命令总览与参数说明

解除权限链接使用的命令是cleos set action permission,完整命令格式如下:

cleos set action permission [OPTIONS] account code type requirement

其中:

参数类型是否必填说明
accountTEXT必填要设置/删除权限动作链接的账户
codeTEXT必填拥有该动作代码的合约账户(即合约部署所在的账户)
typeTEXT必填动作名称。注意权限必须按动作逐个设置
requirementTEXT必填传入NULL表示删除链接;传入权限名表示设置或更新该动作所需的最低权限

常用选项:

选项说明
-h, --help打印帮助信息并退出
-x, --expiration设置交易过期时间(秒),默认 30 秒
-p, --permission授权本次操作所用的账户与权限级别,格式为account@permission,默认account@active
-j, --json以 JSON 格式打印结果
-d, --dont-broadcast不广播交易到网络(仅打印到 stdout)
--return-packed--dont-broadcast配合使用,输出打包后的交易
-r, --ref-block设置用于 TAPOS 的参考区块号或区块 ID
--max-cpu-usage-ms交易执行的 CPU 用量上限(毫秒),默认 0 表示不限制
--max-net-usage交易的网络用量上限(字节),默认 0 表示不限制
--delay-sec设置交易的延迟秒数,默认 0 秒

完整的官方命令参考文档见 docs/02_cleos/03_command-reference/set/set-action-permission.md。

解除权限链接的标准步骤

以下步骤演示如何解除账户alice对合约hodlcontracttransfer动作的权限链接:

cleos set action permission alice hodlcontract transfer NULL

各参数含义:

  • alice= 持有被解除权限链接的账户名;
  • hodlcontract= 拥有该智能合约代码的合约账户名;
  • transfer= 要解除链接的动作名;
  • NULL= 删除该动作上已有的权限链接。

如果不显式指定-p,命令默认以alice@active作为授权签名。更严谨的写法是显式声明授权权限:

cleos set action permission alice hodlcontract transfer NULL -p alice@active

该命令执行成功后,会在终端打印类似如下的输出:

executed transaction: 50fe754760a1b8bd0e56f57570290a3f5daa509c090deb54c81a721ee7048201 120 bytes 242 us # eosio <= eosio::unlinkauth {"account":"alice","code":"hodlcontract","type":"transfer"}

可以看到,链上实际执行的是eosio::unlinkauth原生动作,载荷中只有accountcodetype三个字段,不再包含requirement字段——这正是"解除链接"与"建立链接"(linkauthrequirement字段)在链上数据层面的本质区别。

解除链接后发生了什么

解除成功后,transfer动作不再受自定义最低权限的约束,对合约动作的调用将回到默认授权流程:

  • alice是普通用户账户,调用时使用其active权限即可正常执行;
  • alice是合约账户,且该动作是合约自己发起的(如内联动作),则不再需要链接到eosio.code权限,按常规授权处理。

底层原理:cleos 如何把NULL变成unlinkauth

cleos set action permission的实现在 programs/cleos/main.cpp 中,核心逻辑位于set_action_permission_subcommand结构体(programs/cleos/main.cpp#L959-L988):

permissions->callback([this] { name account = name(accountStr); name code = name(codeStr); name type = name(typeStr); bool is_delete = boost::iequals(requirementStr, "null"); if (is_delete) { send_actions({create_unlinkauth(account, code, type)}, signing_keys_opt.get_keys()); } else { name requirement = name(requirementStr); send_actions({create_linkauth(account, code, type, requirement)}, signing_keys_opt.get_keys()); } });

这段代码揭示了几个关键细节:

  1. NULL的判断是大小写不敏感的:客户端使用boost::iequals(requirementStr, "null")做忽略大小写的字符串比较,因此NULLnullNull均被识别为删除操作,并据此构建unlinkauth动作;
  2. NULL不允许作为权限名使用:一旦命中删除分支,requirement字符串就不会再被解析为name类型,避免与真实权限名混淆;
  3. 构建动作由辅助函数完成create_unlinkauth(programs/cleos/main.cpp#L768-L771)会构造一个chain::action,其authorization取自get_account_permissions(tx_permission, {account, config::active_name}),即默认使用目标账户的active权限作为本交易的授权声明。

链上校验:authorization_manager 如何验证解除操作

unlinkauth动作在链上由系统合约eosio处理。在 eos 仓库中,动作处理器通过宏注册于 libraries/chain/controller.cpp#L278-L279:

SET_APP_HANDLER( eosio, eosio, linkauth ); SET_APP_HANDLER( eosio, eosio, unlinkauth );

对应的鉴权检查实现在 libraries/chain/authorization_manager.cpp 的check_unlinkauth_authorization(libraries/chain/authorization_manager.cpp#L412-L424)中:

void authorization_manager::check_unlinkauth_authorization( const unlinkauth& unlink, const vector<permission_level>& auths )const { EOS_ASSERT( auths.size() == 1, irrelevant_auth_exception, "unlink action should only have one declared authorization" ); const auto& auth = auths[0]; EOS_ASSERT( auth.actor == unlink.account, irrelevant_auth_exception, "the owner of the linked permission needs to be the actor of the declared authorization" ); const auto unlinked_permission_name = lookup_linked_permission(unlink.account, unlink.code, unlink.type); EOS_ASSERT( unlinked_permission_name, transaction_exception, "cannot unlink non-existent permission link of account '${account}' for actions matching '${code}::${action}'", ... ); }

从中可以提炼出解除操作在链上必须满足的三条硬性规则:

  1. 只能有一个授权声明unlinkauth动作必须且只能带一个authorization
  2. 授权者必须是链接归属账户:授权声明的actor必须等于unlink.account,即只有账户本人(或其授权的子权限签名)才能解除自己账户下的链接;
  3. 链接必须真实存在:若该账户对该动作本就没有权限链接,交易会被transaction_exception拒绝并报错cannot unlink non-existent permission link——这解释了为什么对从未链接过的动作重复执行NULL操作会失败,而不是静默成功。

此外,同文件中的check_linkauth_authorization(libraries/chain/authorization_manager.cpp#L375-L410)还对"建立链接"设置了限制:在fix_linkauth_restriction协议特性生效后,不能对eosio系统合约的updateauthdeleteauthlinkauthunlinkauthcanceldelay等敏感系统动作设置最低权限链接。这也意味着这些系统动作同样不应(也不被允许)被随意链接后再解除,相关限制会直接影响你规划权限链接方案的边界。

常见场景与注意事项

  • 解除后权限恢复默认:解除链接只删除"动作 → 最低权限"的映射,不会删除任何权限本身。若要删除自定义权限,应使用cleos set account permission(见 docs/02_cleos/03_command-reference/set/set-account-permission.md)或cleos set account permission ... NULL的权限删除用法。
  • 对未链接的动作执行解除会失败:正如链上校验规则所述,cannot unlink non-existent permission link是正常防护,不属于命令执行错误。
  • 区分"解除链接"与"删除权限":两者是不同层级的操作——前者只影响单个合约动作的鉴权映射,后者影响账户的整个权限结构,误删权限可能导致账户失去控制能力,操作前应谨慎核对账户与权限名。
  • 大小写不敏感但建议规范书写:客户端按忽略大小写的方式识别NULL,社区与官方文档统一使用大写NULL以保持可读性。
  • 合约内联动作场景:如果某合约动作此前被链接到eosio.code以便合约以自身身份发起内联动作,解除链接后该内联调用将不再被该最低权限放行,需改用其他授权方式(如直接使用active)。

相关资源

  • 官方操作指南(本文主题文档):docs/02_cleos/02_how-to-guides/how-to-unlink-permission.md
  • 建立权限链接指南:docs/02_cleos/02_how-to-guides/how-to-link-permission.md
  • 命令参考:docs/02_cleos/03_command-reference/set/set-action-permission.md
  • cleos 客户端实现:programs/cleos/main.cpp
  • 链上鉴权校验:libraries/chain/authorization_manager.cpp
  • 动作处理器注册:libraries/chain/controller.cpp
  • 区块链

【免费下载链接】eos

An open source smart contract platform

项目地址:https://gitcode.com/gh_mirrors/eo/eos
点击查看免费下载

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/24 18:22:58

CentOS磁盘扩容实战:LVM与物理分区在线扩容全攻略

1. 扩容前的系统状态评估1.1 先搞清楚当前磁盘布局给 Centos 做分区扩容&#xff0c;最怕的就是拿到一台机器上来就敲命令。我见过不少朋友在/dev/sda上直接fdisk /dev/sda删分区重建&#xff0c;结果数据全没了&#xff0c;因为根本没有先确认这台机器的底层存储方案到底是什么…

作者头像 李华
网站建设 2026/9/24 18:22:57

Harbor与Hadess制品库对比:Docker Compose部署与nginx升级实战

先抛个问题给正在搭 CI/CD 的各位&#xff1a;你的构建流水线跑得再快&#xff0c;镜像产出后往哪放&#xff1f;几十个微服务、几百个版本的镜像、Helm Chart、SBOM 清单&#xff0c;如果制品管理这块没提前选好&#xff0c;后面投产就是灾难现场。制品管理工具这件事&#xf…

作者头像 李华
网站建设 2026/9/24 18:22:27

BERT情感分析实战:IMDB影评分类Python源码全解析与踩坑指南

简介&#xff1a;基于BERT模型的情感分析项目&#xff0c;面向自然语言处理入门及情感分析应用开发者&#xff0c;提供一套针对IMDB影评数据集进行正面/负面二分类的Python实现。项目包含完整可运行的微调与推理流程&#xff0c;难度适中&#xff0c;适合希望掌握BERT下游任务实…

作者头像 李华
网站建设 2026/9/24 18:20:30

RustFS 1.0.0 GA vs MinIO:实测性能、内存与迁移避坑指南

先说结论&#xff1a;如果你的团队正被 MinIO 的高内存占用、GC 抖动或大量小文件写入的性能瓶颈折磨&#xff0c;RustFS 1.0.0 GA 确实值得放进选型候选名单&#xff1b;但如果你只是觉得 MinIO 用腻了、想换一个“更时髦”的对象存储&#xff0c;我建议你先冷静看完这篇文章再…

作者头像 李华
网站建设 2026/9/24 18:20:26

开发代理不靠记:用direnv、whistle、Nginx管好环境变量与转发规则

先说明一下&#xff0c;这个标题里的“代理”&#xff0c;说的不是大家平时折腾的那种东西&#xff0c;而是开发流程里天天见的三类&#xff1a;环境变量里的 HTTP_PROXY、调试时用来转发请求的本地代理、还有 Nginx 这类反向代理入口。它们的共同点是——数量一多&#xff0c;…

作者头像 李华
网站建设 2026/9/24 18:20:25

SVG path拖动实时移动:用transform代替修改d属性的高效方案

SVG里的path是一条路径&#xff0c;是一条线&#xff0c;也是一个可以随意变形的图形。做矢量编辑工具、做可视化看板、做在线海报设计器&#xff0c;几乎都会碰到这样一个需求&#xff1a;用户想让某个图形跟着鼠标走&#xff0c;实时看到它在画布上的新位置。如果这个图形是r…

作者头像 李华