基于 EOSIO 的区块链使用三种系统资源:RAM、CPU、NET。区块链账户需要足够的系统资源,才能与部署在区块链上的智能合约进行交互。本教程详细介绍了 eosio.system 智能合约中的系统资源模块,适用于 EOS 智能合约的初级开发人员,熟悉如何进行 RAM 的购买与出售、CPU 的质押与取消质押、NET 的质押与取消质押等。
01
概述
(一)RAM 资源简介
1. RAM 是内存资源,区块链存储数据的地方
智能合约在区块链上存储数据的方式,类似于在数据库的操作,可以使用多索引表或单例将其存储在区块链的 RAM 中。基于 EOSIO 的区块链使用 RAM 作为存储介质,拥有其他区块链无法达到的高性能,因此访问区块链数据非常快。
2. RAM 是一种有限的资源,区块链可以有不同的 RAM 政策和规则
例如,公共 EOS 区块链以 64GB 的 RAM 开始,之后区块生产者决定将内存增加到每个区块 1KB,从而不断增加 RAM 的供应,以使其价格不会因区块链应用程序需求的增加而增长过高。
3. RAM 用于执行发送到区块链的许多操作
例如,创建一个新账户操作,需要将新账户的信息存储在区块链内存中;同样,当一个帐户接收一种新型代币时,必须在区块链内存中创建一个新记录,该记录保存接收的新型代币余额,并且区块链上的这块存储空间,必须被转移代币的帐户或接收新型代币的帐户购买。
4. 如果智能合约消耗了所有分配的 RAM,则无法存储任何附加信息
如果智能合约消耗了所有分配的 RAM,要在区块链数据库中继续保存数据,必须满足以下两个条件之一:智能合约释放了一部分占用的 RAM;通过 RAM 购买过程分配给智能合约账户。
(二)CPU 和 NET 资源简介
1. CPU 为区块链账户提供处理能力
帐户拥有的 CPU 数量以微秒为单位,在 cleos get account 命令输出中称为 cpu 带宽。cpu 带宽表示当发送到合约的操作由区块链执行时,帐户可支配的处理时间。区块链执行交易时会消耗 CPU,因此必须抵押足够的 CPU 才能完成交易。
2. NET 为交易提供网络带宽
帐户拥有的 NET 数量以字节为单位,在 cleos get account 命令输出中称为 net 带宽。NET 是一种以空间计价的资源,用于衡量交易在 P2P 层传输过程中消耗的网络份额。区块链执行交易时会消耗 NET,因此必须抵押足够的 NET 才能完成交易。
3. CPU 和 NET 资源由帐户所有者通过质押机制分配
当您为 CPU 和 NET 抵押代币时,您可以访问与所有其他用户在同一时间为同一系统资源抵押的代币总量成比例的系统资源。这意味着您可以免费执行交易,但要在质押代币的限制范围内。无论自由市场有什么变化,质押的代币都能保证资源的比例。如果帐户消耗了所有分配的 CPU 和 NET 资源,此时可以有两个选择:等待区块链补充消耗的资源;通过质押机制分配更多的资源。
4. 区块链自动补充消耗的 CPU 和 NET 资源
在执行交易之前,区块链首先计算执行交易的账户可以消耗多少资源。当数据丢失时,该计算使用带有线性外推的指数移动平均值,并将当前累积平均值乘以(窗口中的块数-自上次更新以来的块数) / (窗口中的块数)。窗口设置为 24 小时窗口。
02
环境准备
(一)一条正在运行且可访问的区块链
中移链(基于 EOS)测试环境搭建:
https://mp.weixin.qq.com/s/NBNFk9Xk9FCukMVgl0tfHA
(二)确保本地钱包已打开并解锁
如何创建钱包:
https://developers.eos.io/manuals/eos/latest/cleos/how-to-guides/how-to-create-a-wallet
(三)已完成 eosio.contracts 的构建和部署
如何构建 eosio.contracts:
https://developers.eos.io/manuals/eosio.contracts/latest/build-and-deploy
(四)已完成 token 的创建、发行和转移
如何创建、发行和转移 token:
https://developers.eos.io/manuals/eosio.contracts/latest/guides/how-to-create-issue-and-transfer-a-token
03
RAM 的操作
(一)购买 RAM
运行以下命令为 testaccount1 账户购买价值 0.1 SYS 的 RAM 资源,其中 eosio=支付 RAM 的账户,testaccount1=接收购买 RAM 的账户,0.1 SYS=为 RAM 支付的代币数量,-p eosio@active=用于授权购买的权限,在本例中为 active 权限。
cleos system buyram eosio testaccount1 "0.1 SYS" -p eosio@active
# 示例输出:
executed transaction: e669b474e985c4346fddcbd98344580d56683a3856874e529d6bff065615c155 128 bytes 466 us
# eosio <= eosio::buyram {"payer":"eosio","receiver":"testaccount1","quant":"0.1000 SYS"}
# eosio.token <= eosio.token::transfer {"from":"eosio","to":"eosio.ram","quantity":"0.0995 SYS","memo":"buy ram"}
# eosio.token <= eosio.token::transfer {"from":"eosio","to":"eosio.ramfee","quantity":"0.0005 SYS","memo":"ram fee"}
# eosio <= eosio.token::transfer {"from":"eosio","to":"eosio.ram","quantity":"0.0995 SYS","memo":"buy ram"}
# eosio.ram <= eosio.token::transfer {"from":"eosio","to":"eosio.ram","quantity":"0.0995 SYS","memo":"buy ram"}
# eosio <= eosio.token::transfer {"from":"eosio","to":"eosio.ramfee","quantity":"0.0005 SYS","memo":"ram fee"}
# eosio.ramfee <= eosio.token::transfer {"from":"eosio","to":"eosio.ramfee","quantity":"0.0005 SYS","memo":"ram fee"}
warning: transaction executed locally, but may not be confirmed by the network yet ]
复制代码
(二)出售 RAM
运行以下命令为 testaccount1 账户出售 1024 Bytes 的 RAM 资源,其中 testaccount1=出售 RAM 资源的账户,1024=出售 RAM 的字节数量,-p testaccount1@active=用于授权出售的权限,在本例中为 active 权限。
cleos system sellram testaccount1 1024 -p testaccount1@active
# 示例输出:
executed transaction: 9a4d3cc802a152cc26ce897571cf95b506cd56aa254becde5efc24f3304cd779 112 bytes 467 us
# eosio <= eosio::sellram {"account":"testaccount1","bytes":1024}
# eosio.token <= eosio.token::transfer {"from":"eosio.ram","to":"testaccount1","quantity":"0.0149 SYS","memo":"sell ram"}
# eosio.token <= eosio.token::transfer {"from":"testaccount1","to":"eosio.ramfee","quantity":"0.0001 SYS","memo":"sell ram fee"}
# eosio.ram <= eosio.token::transfer {"from":"eosio.ram","to":"testaccount1","quantity":"0.0149 SYS","memo":"sell ram"}
# testaccount1 <= eosio.token::transfer {"from":"eosio.ram","to":"testaccount1","quantity":"0.0149 SYS","memo":"sell ram"}
# testaccount1 <= eosio.token::transfer {"from":"testaccount1","to":"eosio.ramfee","quantity":"0.0001 SYS","memo":"sell ram fee"}
# eosio.ramfee <= eosio.token::transfer {"from":"testaccount1","to":"eosio.ramfee","quantity":"0.0001 SYS","memo":"sell ram fee"}
warning: transaction executed locally, but may not be confirmed by the network yet ]
复制代码
04
CPU 的操作
(一)质押 CPU
运行以下命令为 testaccount1 账户质押 0.01 SYS 的 CPU 资源,其中 eosio=为质押 CPU 带宽支付 0.01 SYS 的账户,testaccount1=质押 CPU 带宽的账户,0 SYS=为质押 NET 带宽分配的 SYS 代币数量,0.01 SYS=为质押 CPU 带宽分配的 SYS 代币数量,-p eosio@active=用于授权质押的权限,在本例中为 active 权限。
cleos system sellram testaccount1 1024 -p testaccount1@active
# 示例输出:
executed transaction: 9a4d3cc802a152cc26ce897571cf95b506cd56aa254becde5efc24f3304cd779 112 bytes 467 us
# eosio <= eosio::sellram {"account":"testaccount1","bytes":1024}
# eosio.token <= eosio.token::transfer {"from":"eosio.ram","to":"testaccount1","quantity":"0.0149 SYS","memo":"sell ram"}
# eosio.token <= eosio.token::transfer {"from":"testaccount1","to":"eosio.ramfee","quantity":"0.0001 SYS","memo":"sell ram fee"}
# eosio.ram <= eosio.token::transfer {"from":"eosio.ram","to":"testaccount1","quantity":"0.0149 SYS","memo":"sell ram"}
# testaccount1 <= eosio.token::transfer {"from":"eosio.ram","to":"testaccount1","quantity":"0.0149 SYS","memo":"sell ram"}
# testaccount1 <= eosio.token::transfer {"from":"testaccount1","to":"eosio.ramfee","quantity":"0.0001 SYS","memo":"sell ram fee"}
# eosio.ramfee <= eosio.token::transfer {"from":"testaccount1","to":"eosio.ramfee","quantity":"0.0001 SYS","memo":"sell ram fee"}
warning: transaction executed locally, but may not be confirmed by the network yet ]
复制代码
(二)取消质押 CPU
运行以下命令为 testaccount1 账户取消质押 0.01 SYS 的 CPU 资源,其中 eosio=为质押 CPU 带宽支付 0.01 SYS 的账户,testaccount1=质押 CPU 带宽的账户,0 SYS=为质押 NET 带宽分配的 SYS 代币数量,0.01 SYS=为质押 CPU 带宽分配的 SYS 代币数量,-p eosio@active=用于授权取消质押的权限,在本例中为 active 权限。
cleos system undelegatebw eosio testaccount1 "0 SYS" "0.01 SYS" -p eosio@active
# 示例输出:
executed transaction: e7e7edb6c5556de933f9d663fea8b4a9cd56ece6ff2cebf056ddd0835efa6606 184 bytes 452 us
# eosio <= eosio::undelegatebw {"from":"eosio","receiver":"testaccount1","unstake_net_quantity":"0.0000 SYS","unstake_cpu_qu...
warning: transaction executed locally, but may not be confirmed by the network yet ]
复制代码
05
NET 的操作
(一)质押 NET
运行以下命令为 testaccount1 账户质押 0.01 SYS 的 NET 资源,其中 eosio=为质押 NET 带宽支付 0.01 SYS 的账户,testaccount1=质押 NET 带宽的账户,0 SYS=为质押 NET 带宽分配的 SYS 代币数量,0.01 SYS=为质押 CPU 带宽分配的 SYS 代币数量,-p eosio@active=用于授权质押的权限,在本例中为 active 权限。
cleos system delegatebw eosio testaccount1 "0.01 SYS" "0 SYS" -p eosio@active
# 示例输出:
executed transaction: d25c7deff42f3a420081b8b717820a78a01cf42fc173fe57d305e7ddaebebc12 144 bytes 422 us
# eosio <= eosio::delegatebw {"from":"eosio","receiver":"testaccount1","stake_net_quantity":"0.0100 SYS","stake_cpu_quantity":"0....
# eosio.token <= eosio.token::transfer {"from":"eosio","to":"eosio.stake","quantity":"0.0100 SYS","memo":"stake bandwidth"}
# eosio <= eosio.token::transfer {"from":"eosio","to":"eosio.stake","quantity":"0.0100 SYS","memo":"stake bandwidth"}
# eosio.stake <= eosio.token::transfer {"from":"eosio","to":"eosio.stake","quantity":"0.0100 SYS","memo":"stake bandwidth"}
warning: transaction executed locally, but may not be confirmed by the network yet ]
复制代码
(二)取消质押 NET
运行以下命令为 testaccount1 账户取消质押 0.01 SYS 的 NET 资源,其中 eosio=为质押 NET 带宽支付 0.01 SYS 的账户,testaccount1=质押 NET 带宽的账户,0 SYS=为质押 NET 带宽分配的 SYS 代币数量,0.01 SYS=为质押 CPU 带宽分配的 SYS 代币数量,-p eosio@active=用于授权取消质押的权限,在本例中为 active 权限。
cleos system undelegatebw eosio testaccount1 "0.01 SYS" "0 SYS" -p eosio@active
# 示例输出:
executed transaction: e7e7edb6c5556de933f9d663fea8b4a9cd56ece6ff2cebf056ddd0835efa6606 184 bytes 452 us
# eosio <= eosio::undelegatebw {"from":"eosio","receiver":"testaccount1","unstake_net_quantity":"0.01 SYS","unstake_cpu_qu...
warning: transaction executed locally, but may not be confirmed by the network yet ]
复制代码
06
常见问题
(一)执行 sellram 方法时报错:eosio_assert_message assertion failure?
解答:出售的 RAM 字节数太少了,没有达到 0.0001 SYS 对应的最小字节数,需要多出售一些字节数量。
(二)质押 CPU 和 NET 资源的代币单位是啥,如何查询呢?
解答:质押 CPU 和 NET 资源的代币单位一般是 SYS,这是通过系统合约定义的,可以通过 cleos get account 查询到 CPU、NET 用量的代币单位。
(三)关于 EOS 的三种资源:RAM、NET、CPU,数量单位分别是什么,以及如何计算剩余数量?
解答:可以 cleos get account 查询到剩余资源信息,其中 RAM 资源的单位是 byte,剩余 RAM 数量对应字段:quota - used;NET 资源的单位也是 byte,剩余 NET 数量对应字段:available;CPU 资源的单位是 us,剩余 CPU 数量对应字段:available。
(四)关于一次性初始化足够多的 RAM、CPU、NET 资源,为啥不建议这么操作?
解答:RAM 对应服务器的内存资源,分配过多可能影响其他服务运行。通过计算一万份 DDC 所消耗的 RAM,可以预估出每一份 DDC 所需的 RAM,从而根据业务需要一段时间充值一次就行。CPU 和 NET 资源是质押机制的,交易完成后会在 24 小时内会线性返还,因此充值一天所需的 CPU 和 NET 资源就行。
-END-
评论