ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

EOSIO cleos get servants 命令详解:查询账户控制关系与受控账户

EOSIO cleos get servants 命令详解:查询账户控制关系与受控账户 区块链【免费下载链接】eosAn open source smart contract platform项目地址https://gitcode.com/gh_mirrors/eo/eos点击查看免费下载导读cleos get servants是 EOSIO 智能合约平台中用于查询给定账户所控制的所有账户servants即仆人账户的命令行工具。它通过调用节点上的 history_plugin 提供的get_controlled_accounts接口反向解析账户权限体系中控制账户 → 受控账户的授权关系是开发者审计账户权限结构、排查权限委托链、管理多签账户体系时的高频排查命令。阅读本文后你将掌握该命令的完整用法、JSON 返回结构、底层数据索引原理以及它与其他cleos get系列命令如cleos get accounts的本质区别。一、命令概览cleos get servants的语义是Retrieve accounts which are servants of a given account检索指定账户所控制的仆人账户。cleos get servants不带参数直接运行时命令会输出使用帮助Usage: cleos get servants account Positionals: account TEXT The name of the controlling account参数类型必填说明accountTEXT是控制账户controlling account的名称即要查询它控制了哪些账户的账户名该命令只接受一个位置参数account且为必填项若缺失CLI 框架会直接打印上述 Usage 并退出。二、典型用法与输出解析2.1 查询命令以查询账户inita所控制的账户为例cleos get servants inita2.2 返回结果命令执行成功后输出如下 JSON{ controlled_accounts: [ tester ] }返回结构只有一个核心字段controlled_accounts由受控账户名组成的数组。上述输出表示tester是inita的受控账户即inita在tester的权限结构中扮演了授权角色。2.3 空结果场景如果指定账户没有控制任何其他账户则返回空数组{ controlled_accounts: [] }这在权限审计中同样是有价值的信息表明该账户当前未作为任何其他账户权限的授权方。三、命令背后的调用链从 CLI 到插件cleos get servants并非直接查询链上状态数据库的通用查询而是依赖 history_plugin 的只读 API实现的。完整调用链如下3.1 CLI 侧定义在 programs/cleos/main.cpp 中get子命令组注册了servants子命令// get servants string controllingAccount; auto getServants get-add_subcommand(servants, localized(Retrieve accounts which are servants of a given account )); getServants-add_option(account, controllingAccount, localized(The name of the controlling account))-required(); getServants-callback([] { auto arg fc::mutable_variant_object( controlling_account, controllingAccount); std::cout fc::json::to_pretty_string(call(get_controlled_accounts_func, arg)) std::endl; });可以看到cleos get servants把位置参数account包装成controlling_account字段并通过get_controlled_accounts_func对应的 HTTP 端点发起请求最终以格式化 JSONfc::json::to_pretty_string打印结果。3.2 HTTP 端点在 programs/cleos/httpc.hpp 中定义了该端点const string history_func_base /v1/history; const string get_controlled_accounts_func history_func_base /get_controlled_accounts;即实际调用的是节点 RPC 接口POST /v1/history/get_controlled_accounts注意路径前缀是history而非chain请求体为{controlling_account: 账户名}。3.3 插件侧实现该 RPC 由 history_plugin 暴露。在 plugins/history_plugin/history_plugin.cpp 中read_only::get_controlled_accounts_results read_only::get_controlled_accounts(const get_controlled_accounts_params params) const { std::setaccount_name accounts; const auto db history-chain_plug-chain().db(); const auto account_control_idx db.get_indexaccount_control_history_multi_index, by_controlling(); auto range account_control_idx.equal_range( params.controlling_account ); for (auto obj range.first; obj ! range.second; obj) accounts.insert(obj-controlled_account); return {vectoraccount_name(accounts.begin(), accounts.end())}; }实现逻辑很清晰通过history-chain_plug-chain().db()访问节点内存中的 chainbase 状态数据库取出account_control_history_multi_index索引并以by_controlling作为查询键equal_range找出所有controlling_account params.controlling_account的记录收集每条记录的controlled_account字段到std::set自动去重、排序返回controlled_accounts数组。参数与结果的数据结构定义在 plugins/history_plugin/include/eosio/history_plugin/history_plugin.hppstruct get_controlled_accounts_params { chain::account_name controlling_account; }; struct get_controlled_accounts_results { vectorchain::account_name controlled_accounts; }; get_controlled_accounts_results get_controlled_accounts(const get_controlled_accounts_params params) const;RPC 路由注册位于 plugins/history_api_plugin/history_api_plugin.cppCHAIN_RO_CALL(get_controlled_accounts, http_params_types::params_required)其中params_required表明该接口强制要求请求体包含参数这也与测试中空参数返回错误码 3200006 的行为一致见下文第四节。四、底层数据account_control_history 索引如何构建4.1 索引对象结构get_controlled_accounts查询的索引由 plugins/history_plugin/include/eosio/history_plugin/account_control_history_object.hpp 定义每个索引对象包含三个字段字段类型含义controlled_accountaccount_name受控账户仆人账户controlled_permissionpermission_name受控账户中被授权的权限名如 owner/activecontrolling_accountaccount_name控制账户授权方该索引在by_controlling维度上以(controlling_account, id)构成复合唯一键保证按控制账户的高效范围查询同时by_controlled_authority以(controlled_account, controlled_permission, controlling_account)支持反向查询。4.2 索引数据从何而来这些记录并非链上共识状态而是history_plugin 在监听到特定系统动作时增量构建的历史索引。在 plugins/history_plugin/history_plugin.cpp 的on_system_action中if( at.act.name newaccount_n ) { const auto create at.act.data_aschain::newaccount(); add(db, create.owner.keys, create.name, owner_n); add(db, create.owner.accounts, create.name, owner_n); add(db, create.active.keys, create.name, active_n); add(db, create.active.accounts, create.name, active_n); } else if( at.act.name updateauth_n ) { const auto update at.act.data_aschain::updateauth(); ... }具体写入逻辑在add()方法history_plugin.cppstatic void add(chainbase::database db, const vectorpermission_level_weight controlling_accounts, const account_name account_name, const permission_name permission) { for (auto controlling_account : controlling_accounts ) { db.createaccount_control_history_object( { obj.controlled_account account_name; obj.controlled_permission permission; obj.controlling_account controlling_account.permission.actor; }); } }也就是说当发生newaccount创建账户动作时新账户 owner/active 权限中accounts字段即由其他账户作为权限权重的每个授权账户都会被记录为控制账户当发生updateauth更新权限动作时权限变更涉及的账户控制关系会同步更新对应 history_plugin.cpp 中的removeaccount_control_history_multi_index, by_controlled_authority(...)删除逻辑。因此可以得出关键结论cleos get servants反映的是由其他账户而非公钥参与授权形成的账户控制关系典型场景是账户 A 将自己的某个权限交由账户 B 参与多签或使用eosio newaccount的--account选项为账户指定账户级授权方。这与按公钥反查账户的cleos get accounts命令形成互补前者查账户间的授权控制后者查密钥与账户的关联。五、测试验证与常见问题5.1 仓库内自动化测试tests/plugin_http_api_test.py 对底层get_controlled_accountsHTTP 接口进行了完整验证# get_controlled_accounts with empty parameter default_cmd cmd_base get_controlled_accounts ret_json Utils.runCmdReturnJson(default_cmd) self.assertEqual(ret_json[code], 400) self.assertEqual(ret_json[error][code], 3200006) # get_controlled_accounts with empty content parameter ... # get_controlled_accounts with invalid parameter ... # get_controlled_accounts with valid parameter valid_cmd default_cmd self.http_post_str ({\controlling_account\:\test\}) ret_json Utils.runCmdReturnJson(valid_cmd) self.assertIn(controlled_accounts, ret_json)测试覆盖了四种场景空参数HTTP 400错误码 3200006缺失必需参数空内容请求体同样返回 400/3200006非法参数同样返回 400/3200006合法参数返回 JSON 中必须包含controlled_accounts字段。此外tests/Node.py 中测试框架解析节点信息时也使用servantstrans[controlled_accounts]读取该字段说明该结构被测试基础设施广泛依赖。5.2 常见问题排查现象原因处理建议命令报错Error 3200006: Invalid http request未提供account参数补全参数如cleos get servants inita返回 404 / 接口不存在节点未启用 history_plugin在 nodeos 启动参数中加入--plugin eosio::history_plugin与--plugin eosio::history_api_plugin并重启节点注意该插件需要从创世块或足够早的高度开始同步才能拥有完整历史索引返回controlled_accounts为空该账户确实没有账户级受控关系或节点历史数据不完整结合cleos get accounts 公钥交叉验证权限归属查询结果与链上权限不符索引由 history_plugin 增量维护非链上共识数据确认节点已追上最新高度且插件过滤配置filter-on/filter-out未屏蔽newaccount/updateauth动作六、与其他 get 系列命令的联动cleos get servants属于cleos get命令族通常与以下命令组合使用以完成完整的权限审计cleos get account 账户名查看账户本身的权限结构owner/active 权限及其权重cleos get accounts 公钥反查哪些账户的权限中包含指定公钥cleos get servants 账户名反查哪些账户的权限中包含指定账户本文主角。三者配合可以从账户 → 权限结构 → 公钥 → 账户多个方向交叉验证整个授权网络例如排查某个多签账户的所有实际控制者、确认某个账户是否被其他账户接管等。可参考 cleos get 命令参考目录 了解命令族全貌其底层 API 背景可查阅 history_api_plugin 文档。七、小结cleos get servants虽是一个参数极简的查询命令其背后却串起了 EOSIO 完整的账户权限 → 历史索引 → RPC → CLI链路概念上它回答指定账户控制了哪些账户这一问题是账户级授权关系而非公钥级的反向查询实现上它由 history_plugin 通过监听newaccount、updateauth系统动作增量维护account_control_history索引再经/v1/history/get_controlled_accounts暴露使用上只需一个account位置参数即可获得结构化的controlled_accountsJSON 结果适合在脚本化审计与测试框架中直接消费。理解其底层索引构建机制后也能解释为什么新部署的节点查询结果可能为空——因为该数据依赖 history_plugin 自部署以来的持续记录而非从链上状态直接还原这在实际运维排查中是必须注意的前提条件。赞分享区块链【免费下载链接】eosAn open source smart contract platform项目地址https://gitcode.com/gh_mirrors/eo/eos点击查看免费下载相关推荐EOSIO cleos get accounts 命令详解按公钥查询关联账户EOSIO cleos get accounts 命令详解按公钥查询关联账户 导读 cleos get accounts 是 EOSIO 命令行客户端 cle区块链EOSIO cleos get currency balance 命令详解查询账户代币余额的完整指南EOSIO cleos get currency balance 命令详解查询账户代币余额的完整指南 导读 cleos get currency balanc区块链EOSIO cleos system listbw 命令详解查询账户委托带宽Delegated BandwidthEOSIO cleos system listbw 命令详解查询账户委托带宽Delegated Bandwidth 导读 cleos system lis区块链创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表