ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

eos 智能合约作用域查询指南:`cleos get scope` 命令详解与源码解析

eos 智能合约作用域查询指南:`cleos get scope` 命令详解与源码解析 区块链【免费下载链接】eosAn open source smart contract platform项目地址https://gitcode.com/gh_mirrors/eo/eos点击查看免费下载cleos get scope是 eos 区块链命令行工具集programs/cleos中用于**枚举某个智能合约账户所拥有的全部表作用域scope与表table**的只读查询命令。它回答了一个在开发与运维中非常常见的问题eosio.token这类合约到底在哪些账户作用域下维护了哪些表、每个表有多少行数据、RAM 由谁支付。读完本文你将完整掌握该命令的位置参数与全部选项的语义、输出字段含义、基于more字段的分页技巧以及从 CLI 到 RPC 再到链插件底层的完整调用链实现原理。命令概览作用域与表的关系在 eos 的存储模型中多索引表multi-index table由三元组唯一标识code合约账户→ scope作用域→ table表名。其中code是部署合约的账户即表的所有者scope是数据的隔离分区通常是一个账户名例如eosio.token合约会为每个持有代币的账户各自维护一份accounts表table是表名与合约 ABI 中声明的表结构对应。cleos get table见 docs/02_cleos/03_command-reference/get/table.md用于读取指定account scope table下的具体数据行而cleos get scope则向上一个层级列出某个合约名下所有已存在的 scope/table 组合相当于先侦察合约的存储布局再决定去读取哪张表。两者搭配使用是排查合约数据的最常用组合拳。位置参数参数类型是否必填说明contractTEXT是拥有这些表的合约账户名即表的所有者对应 RPC 参数code在 programs/cleos/main.cpp 中该参数通过getScope-add_option( contract, code, ... )-required()注册为必填auto getScope get-add_subcommand( scope, localized(Retrieve a list of scopes and tables owned by a contract)); getScope-add_option( contract, code, localized(The contract who owns the table) )-required();选项详解选项类型说明-t, --tableTEXT表名过滤条件仅返回指定名称的表可选-l, --limitUINT返回的最大行数可选服务端默认值为 10-L, --lowerTEXTscope 的下界lower bound可选用于范围查询与翻页-U, --upperTEXTscope 的上界upper bound可选-r, --reverse标志以逆序迭代返回结果可选这些选项在 programs/cleos/main.cpp 中逐一注册回调中将它们打包为 JSON 请求体getScope-add_option( -t,--table, table, localized(The name of the table as filter) ); getScope-add_option( -l,--limit, limit, localized(The maximum number of rows to return) ); getScope-add_option( -L,--lower, lower, localized(Lower bound of scope) ); getScope-add_option( -U,--upper, upper, localized(Upper bound of scope) ); getScope-add_flag(-r,--reverse, reverse, localized(Iterate in reverse order)); getScope-callback([] { auto result call(get_table_by_scope_func, fc::mutable_variant_object(code,code) (table,table) (lower_bound,lower) (upper_bound,upper) (limit,limit) (reverse, reverse) ); std::cout fc::json::to_pretty_string(result) std::endl; });其中get_table_by_scope_func在 programs/cleos/httpc.hpp 中定义为const string get_table_by_scope_func chain_func_base /get_table_by_scope;即该命令最终发送的 HTTP 请求为POST /v1/chain/get_table_by_scope。选项语义的补充说明--limit默认值与-l缺省CLI 层不强制要求--limit服务端结构体默认limit 10见 plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp因此不带-l时默认最多返回 10 行。--lower/--upper作用于 scope这两个边界作用于 scope 字段按 uint64 数值排序并非作用于表名。当--lower或--upper传入的是普通账户名时会被内部解析为 uint64 数值name的本质就是一个 64 位整数参与范围比较。--table是精确过滤而非模糊匹配它按表名做精确筛选不传则返回该合约下所有 scope/table 组合。输出格式rows、more 与分页服务端返回的 JSON 结构在 plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp 中定义struct get_table_by_scope_result_row { name code; // 合约账户 name scope; // 作用域 name table; // 表名 name payer; // 该表项的 RAM 支付者 uint32_t count; // 该 scopetable 下的数据行数 }; struct get_table_by_scope_result { vectorget_table_by_scope_result_row rows; string more; /// fill lower_bound with this value to fetch more rows };对应的序列化反射为FC_REFLECT( eosio::chain_apis::read_only::get_table_by_scope_result_row, (code)(scope)(table)(payer)(count)); FC_REFLECT( eosio::chain_apis::read_only::get_table_by_scope_result, (rows)(more) );输出示例格式示意假设查询eosio.token合约下的所有表cleos get scope eosio.token返回结果形如{ rows: [{ code: eosio.token, scope: eosio, table: accounts, payer: eosio, count: 1 },{ code: eosio.token, scope: alice, table: accounts, payer: alice, count: 3 },{ code: eosio.token, scope: bob, table: accounts, payer: bob, count: 2 } ], more: carol }字段含义rows命中的 scope/table 组合列表。每一行的code恒等于查询的合约名scope是作用域通常是账户名table是表名payer是该表项的 RAM 支付者账户count是该表在该作用域下的行数。more分页游标。当返回行数达到limit且有更多数据时more会被设置为下一段的起始 scope 值此时只需把more的值作为下一次请求的--lower即可继续拉取后续数据。当没有更多数据时more为空字符串。分页示例# 第一页默认 limit10 cleos get scope eosio.token # 下一页把上一页返回的 more 值作为 lower 继续查询 cleos get scope eosio.token -L carol这种用more填充lower_bound的游标翻页方式由结构体注释/// fill lower_bound with this value to fetch more rows明确约定与cleos get table的分页机制保持一致。源码级原理从 RPC 入口到链插件实现RPC 入口注册/v1/chain/get_table_by_scope作为只读接口注册在 plugins/chain_api_plugin/chain_api_plugin.cppCHAIN_RO_CALL(get_table_by_scope, 200, http_params_types::params_required),CHAIN_RO_CALL表明这是一个不修改链状态、不产生交易的只读查询返回 HTTP 200 并强制要求请求体包含参数。服务端实现要点核心实现在 plugins/chain_plugin/chain_plugin.cpp 的read_only::get_table_by_scope中其关键逻辑如下构造查询区间以(code, scope, table)三元组构建下界与上界查找元组默认区间覆盖该合约下所有 scope/table若提供了lower_bound/upper_bound则将其解析为uint64_t并替换 scope 分量auto lower_bound_lookup_tuple std::make_tuple( p.code, name(std::numeric_limitsuint64_t::lowest()), p.table ); auto upper_bound_lookup_tuple std::make_tuple( p.code, name(std::numeric_limitsuint64_t::max()), (p.table.empty() ? name(std::numeric_limitsuint64_t::max()) : p.table) ); if( p.lower_bound.size() ) { uint64_t scope convert_to_typeuint64_t(p.lower_bound, lower_bound scope); std::get1(lower_bound_lookup_tuple) name(scope); }区间有效性检查若上界小于下界直接返回空结果此时more为空if( upper_bound_lookup_tuple lower_bound_lookup_tuple ) return result;遍历表索引通过table_id_multi_index的by_code_scope_table索引定位区间正向或逆向遍历reverse时使用boost::make_reverse_iteratorconst auto idx d.get_indexchain::table_id_multi_index, chain::by_code_scope_table(); auto lower idx.lower_bound( lower_bound_lookup_tuple ); auto upper idx.upper_bound( upper_bound_lookup_tuple ); if( reverse ) { walk_table_range( boost::make_reverse_iterator(upper), boost::make_reverse_iterator(lower) ); } else { walk_table_range( lower, upper ); }行数上限与游标table_receiver内部通过check_limit()在rows.size() limit时置位reached_limit_并停止遍历当迭代器未走到区间末尾时将itr-scope.to_string()写入more作为翻页游标见 chain_plugin.cpp 与walk_table_range中的result.more itr-scope.to_string();。表名过滤table_receiver::add_table_row中if( params_.table row.table ! params_.table ) return;实现--table的精确过滤。关于 backing store 的限制重要前提该查询的 chainbase 分支实现完整但从源码可见当节点配置的 backing store 非 chainbase如 RocksDB时get_table_by_scope会抛出Support for configured backing_store has not been added to get_table_by_scope见 chain_plugin.cpp 与 chain_plugin.cpp。因此在使用非默认 backing store 的节点上执行该命令可能失败这是由当前仓库实现决定的使用前提。常见用法与最佳实践1. 查看合约存储布局查询一个合约例如系统合约或代币合约到底占用了哪些作用域与表cleos get scope eosio.token cleos get scope eosio.system2. 结合cleos get table深入读取先用get scope定位目标作用域与表名再用get table读取实际数据# 1) 找出 eosio.token 的所有 scope cleos get scope eosio.token # 2) 读取某个 scope 下的 accounts 表 cleos get table eosio.token eosio accounts3. 精确过滤与范围查询只想看某个合约下名为accounts的表或限定 scope 在指定账户名区间# 按表名过滤 cleos get scope eosio.token -t accounts # 限定 scope 范围从 alice 开始到 bob 结束 cleos get scope eosio.token -L alice -U bob # 逆序遍历 cleos get scope eosio.token -r4. 大数据量翻页当合约作用域数量超过limit时务必检查返回的more字段并携带-L继续拉取避免遗漏cleos get scope eosio.token -l 100 cleos get scope eosio.token -l 100 -L 上页more值小结cleos get scope是 eos 生态中快速掌握合约数据布局的入口级命令它由 programs/cleos/main.cpp 定义 CLI 参数通过POST /v1/chain/get_table_by_scope注册于 plugins/chain_api_plugin/chain_api_plugin.cpp转发至链插件由 chain_plugin.cpp 中基于by_code_scope_table索引的区间遍历完成查询。掌握--table/--lower/--upper/--limit/--reverse五个选项的组合使用以及rows/more输出字段的分页语义即可高效地探查任意合约的存储结构并为后续的get table精确数据读取铺平道路。赞分享区块链【免费下载链接】eosAn open source smart contract platform项目地址https://gitcode.com/gh_mirrors/eo/eos点击查看免费下载相关推荐使用 cleos get table 查询 EOS 智能合约表数据从入门到源码级解析使用 cleos get table 查询 EOS 智能合约表数据从入门到源码级解析 本篇指南围绕 EOS 区块链的核心数据检索操作展开通过命令行工具 cl区块链用 LQL 编写 BigQuery 日志查询skills29 cloud-logging-query-generation 技能中的查询参考与实战模式用 LQL 编写 BigQuery 日志查询skills29 cloud logging query generation 技能中的查询参考与实战模式 Big区块链eos 节点验证cleos get schedule 命令详解与生产者调度表Producer Schedule查询实战eos 节点验证cleos get schedule 命令详解与生产者调度表Producer Schedule查询实战 导读 在 EOSIO 智能合约平台区块链创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表