EOSIO cleos system undelegatebw 实战指南:撤销已委托的 CPU 带宽
2026/9/24 9:03:52 网站建设 项目流程
  • 区块链

【免费下载链接】eos

An open source smart contract platform

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

本指南以 EOSIO 官方cleos客户端为操作主线,讲解如何使用cleos system undelegatebw撤销此前通过delegatebw委托给其他账户的 CPU(及 NET)带宽资源。读完本文,你将掌握该命令的完整参数语义、常用选项、底层实现原理与验证方法,能够在实际链上安全、准确地执行带宽撤销操作。

目标:撤销为账户或应用委托的资源

在 EOSIO 网络中,账户间的 CPU 与 NET 带宽通过delegatebw动作进行委托(delegate)。当业务场景变化——例如合作方不再需要你为其质押的带宽、或你自己需要收回质押的 CPU 资源时,就需要使用undelegatebw动作来撤销(undelegate)这部分资源。

执行撤销操作时,必须牢记一条硬性约束:

只有当初发起委托的账户(原始委托方)才能撤销对应的带宽资源。被委托方或其他任何第三方账户都无法代为撤销。

这一点在 how-to-undelegate-CPU.md 中有明确警示("Beware that only the account which originally delegated resource can undelegate"),也是整个撤销流程最重要的前提。

开始之前:前置条件与概念准备

在执行撤销操作前,请确认以下条件与概念:

  1. 安装受支持的cleos版本cleos随 EOSIO 软件一同发布,安装 EOSIO 即会安装cleos,具体安装方式参见 00_install。本仓库中cleos的入口实现位于 programs/cleos/main.cpp。
  2. 确保系统合约已部署eosio.contracts仓库中的参考系统合约(reference system contracts)必须已部署并用于管理系统资源。undelegatebw动作最终由系统合约中的eosio账户处理,本仓库本身不包含该系统合约源码,cleos只负责构造并发送该动作。
  3. 理解以下基础概念
    • 账户(Account):EOSIO 网络中的基本身份单元,资源的委托与撤销都以账户为粒度;
    • 网络带宽(NET Bandwidth):决定账户每单位时间内可发送交易字节数上限的资源;
    • CPU 带宽(CPU Bandwidth):决定账户交易执行可用 CPU 时间上限的资源。

核心操作:撤销 0.01 SYS 的 CPU 带宽

以下命令将此前从账户bob委托给账户alice0.01 SYSCPU 带宽撤销回来(本示例来自 how-to-undelegate-CPU.md):

cleos system undelegatebw bob alice "0 SYS" "0.01 SYS"

命令执行成功后,会得到类似如下的输出:

executed transaction: e7e7edb6c5556de933f9d663fea8b4a9cd56ece6ff2cebf056ddd0835efa6606 184 bytes 452 us # eosio <= eosio::undelegatebw {"from":"alice","receiver":"bob","unstake_net_quantity":"0.0000 EOS","unstake_cpu_qu... warning: transaction executed locally, but may not be confirmed by the network yet ]

输出含义解析:

  • executed transaction: <txid>:交易 ID,随后是交易字节数(184 bytes)与本地执行耗时(452 us);
  • # eosio <= eosio::undelegatebweosio系统账户接收并执行了undelegatebw动作,动作载荷中包含from(委托方)、receiver(被委托方)、unstake_net_quantity(撤销的 NET 数量)与unstake_cpu_quantity(撤销的 CPU 数量);
  • 末尾的warning是正常提示:交易已在本地节点执行,但尚未确认上链。

位置参数逐一说明

根据命令参考文档 system-undelegatebw.md,该命令包含 4 个必填位置参数:

参数类型说明
fromTEXT撤销带宽的账户(即原始委托方)
receiverTEXT被撤销带宽的账户(即此前接收委托的账户)
unstake_net_quantityTEXT为 NET 带宽撤销的 EOS/SYS 数量
unstake_cpu_quantityTEXT为 CPU 带宽撤销的 EOS/SYS 数量

因此cleos system undelegatebw bob alice "0 SYS" "0.01 SYS"的含义是:委托方bob从接收方alice处撤销0.01 SYS的 CPU 带宽,NET 部分撤销0 SYS。数量字符串必须带精度(如"0.01 SYS"),且需与链上符号(Symbol)一致。

需要留意的是,命令行中fromreceiver的先后顺序与自然语言描述容易混淆,请严格以命令参考文档中的参数顺序(先fromreceiver)为准。

命令选项详解:控制交易签名、广播与费用预算

undelegatebw复用 cleos 的标准交易选项(同样来自 system-undelegatebw.md),可在实际使用中按需组合:

选项说明
-h, --help打印帮助信息并退出
-x, --expirationTEXT设置交易过期时间(秒),默认 30s
-f, --force-unique强制交易唯一,会消耗额外带宽,用于防止意外重复提交相同交易
-s, --skip-sign跳过签名(不使用钱包密钥签名)
-d, --dont-broadcast不广播交易到网络(仅打印到 stdout)
-r, --ref-blockTEXT设置 TAPOS(Transaction as Proof-of-Stake)使用的参考区块号或区块 ID
-p, --permissionTEXT授权使用的账户与权限级别,格式account@permission,默认account@active
--max-cpu-usage-msUINT设置交易执行的 CPU 预算上限(毫秒),默认 0 表示不限制
--max-net-usageUINT设置交易的 NET 用量预算上限(字节),默认 0 表示不限制
--delay-secUINT设置交易延迟秒数,默认 0s
-j, --json以 JSON 格式打印结果

常用组合示例——只打印交易内容而不广播(可用于预先审查):

cleos system undelegatebw bob alice "0 SYS" "0.01 SYS" -d -j

源码级剖析:cleos 如何构造 undelegatebw 动作

cleos system undelegatebw的底层实现在 programs/cleos/main.cpp 的undelegate_bandwidth_subcommand结构中。从源码可以看到完整的数据流:

undelegate_bandwidth->add_option("from", from_str, localized("The account undelegating bandwidth"))->required(); undelegate_bandwidth->add_option("receiver", receiver_str, localized("The account to undelegate bandwidth from"))->required(); undelegate_bandwidth->add_option("unstake_net_quantity", unstake_net_amount, localized("The amount of tokens to undelegate for network bandwidth"))->required(); undelegate_bandwidth->add_option("unstake_cpu_quantity", unstake_cpu_amount, localized("The amount of tokens to undelegate for CPU bandwidth"))->required(); add_standard_transaction_options_plus_signing(undelegate_bandwidth, "from@active");

其回调函数则完成动作载荷的构造与发送:

undelegate_bandwidth->callback([this] { fc::variant act_payload = fc::mutable_variant_object() ("from", from_str) ("receiver", receiver_str) ("unstake_net_quantity", to_asset(unstake_net_amount)) ("unstake_cpu_quantity", to_asset(unstake_cpu_amount)); auto accountPermissions = get_account_permissions(tx_permission, {name(from_str), config::active_name}); send_actions({create_action(accountPermissions, config::system_account_name, "undelegatebw"_n, act_payload)}, signing_keys_opt.get_keys()); });

关键实现事实:

  • 动作目标:动作发送到config::system_account_name(即eosio系统账户),动作名为undelegatebw,由已部署的系统合约执行资源账本更新;
  • 数量转换:用户输入的字符串数量经to_asset()转换为asset类型,保证精度与符号合法性;
  • 默认权限:默认使用from@active权限签名(add_standard_transaction_options_plus_signing(undelegate_bandwidth, "from@active")),也解释了为何只有from账户(原始委托方)能发起该操作——权限模型天然约束了操作主体;
  • 注意对比:与delegatebw(实现于 programs/cleos/main.cpp)不同,undelegatebw的载荷只有fromreceiverunstake_net_quantityunstake_cpu_quantity四个字段,没有transfer标志——带宽一旦撤销,其投票权与撤销权默认回归委托方。

相关操作:自我撤销(unstake)与 NET 撤销

撤销自己账户的带宽(unstake 场景)

当委托方与接收方是同一账户时(即自己给自己质押带宽),撤销操作退化为常见的 "unstake" 场景。参考 how-to-unstake-CPU.md,撤销alice自己账户0.01 SYSCPU 带宽的命令为:

cleos system undelegatebw alice alice "0.01 SYS" "0 SYS"

此时fromreceiver均为alice,动作载荷为{"from":"alice","receiver":"alice",...}

撤销 NET 带宽

同样的命令结构也适用于 NET 带宽的撤销,参考 how-to-undelegate-NET.md,将 CPU 数量的0.01 SYS移到 NET 位置即可:

cleos system undelegatebw bob alice "0.01 SYS" "0 SYS"

与委托命令的对照

撤销操作是委托操作的逆过程,委托命令见 how-to-delegate-CPU-resource.md:

cleos system delegatebw bob alice "0 SYS" "0.01 SYS"

两者参数一一对应(stake_net_quantity/stake_cpu_quantity对应撤销时的unstake_net_quantity/unstake_cpu_quantity),完整的参数对照可查阅命令参考文档 system-delegatebw.md 与 system-undelegatebw.md,命令总索引见 system/index.md。

测试与验证:仓库中的撤销用例

本仓库的单元测试基建为我们提供了撤销操作的验证模板。在 unittests/eosio_system_tester.hpp 中,eosio_system_tester测试工具封装了unstake辅助函数,其构造的动作与cleos完全一致:

action_result unstake( const account_name& from, const account_name& to, const asset& net, const asset& cpu ) { return push_action( name(from), "undelegatebw"_n, mvo() ("from", from) ("receiver", to) ("unstake_net_quantity", net) ("unstake_cpu_quantity", cpu) ); }

这印证了两点事实:

  1. undelegatebw动作的标准载荷字段即为fromreceiverunstake_net_quantityunstake_cpu_quantity,与 unittests/contracts/eosio.system/eosio.system.abi 中声明的 ABI 一致;
  2. 测试中以from账户为签名者推送动作,再次确认了"只有原始委托方才能撤销"的权限模型。

同时,tests/Node.py 等集成测试脚本中也有对undelegatebw的调用覆盖,可用于端到端流程验证。

注意事项与常见问题

  • 只有原始委托方可以撤销:若账户 A 曾将带宽委托给 B,只有 A 能发起undelegatebw,B 或第三方账户无权操作;撤销后资源回归 A,而非自动归属 B。
  • 不能超额撤销:撤销数量不能超过此前委托的数量,否则系统合约会拒绝该动作。
  • 交易确认:输出中的warning: transaction executed locally, but may not be confirmed by the network yet属正常提示,最终以上链后的区块确认为准。
  • 资源回收时机undelegatebw动作由系统合约处理,撤销的 token 会进入系统合约的资源回收流程,具体到账时机取决于系统合约实现(该合约源码不在本仓库内,来自独立的eosio.contracts仓库)。
  • 权限设置:默认使用from@active权限,如委托方使用自定义权限管理资源,可通过-p选项显式指定。
  • 区块链

【免费下载链接】eos

An open source smart contract platform

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

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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询