【EOSIO 设计规格文档】由合约支付事务的开销
image.png在 EOSIO 设计规格文档库中,列出来了一个很多项目方/用户会感兴趣的功能:由合约支付事务的开销。今天一起来了解下。
文档库链接: https://github.com/EOSIO/spec-repo
编译者: EOS42 荆凯
译文如有转载,请注明来源和原文作者。免责声明
本文仅为与 EOSIO 社区中文开发者分享信息之用,限于编者认知水平与信息完整度等方面的限制,有可能存在信息不完整、观点不当等因素,仍需待读者自行独立思考。本文不构成任何投资建议。
摘要
智能合约可以承担事务的开销(NET 和 CPU )。这一特性,让无资源或少资源的用户可以使用应用程序,而无需这些应用对原始的事务进行联合签名。
简述
EOSIO 区块链会就用户发起的事务收取用户 NET 和 CPU 的成本。这些开销是暂时的; 超过24小时之后,CPU 和 NET 会重新恢复。用户可以在一组事务上耗尽其所有的资源,而24小时之后,又可以重新操作。
尽管对每个用户而言这些成本很低,但是对于(想要为用户支付资源开销的)应用程序提供者而言,该部分资源的成本可以迅速累加。例如,如果应用程序提供者想要赞助 1000 个账号,为其提供免费的资源,而每个账号需要 Xpeek 的 CPU 和 Ypeek 的 NET,那么,该应用提供者需要抵押
1000 * Xpeek 的 CPU 以及 1000 * Ypeek 的 NET。在这一模型下,用户可以利用这些资源去使用其他的应用,而不是在你的程序之中使用该部分资源。此外,大部分这些资源可能是闲置的。
(在Nodeos 1.8 之中的)ONLY_BILL_FIRST_AUTHORIZER 这一特性,通过只向事务的首个授权方收费的方式,部分地解决了这个问题。这一特性允许应用提供者对用户的每一笔事务进行联合签名,通过这一方式从公共池中支付事务的开销。
(译者注: 利用 1.8的共识升级特征, dApp 方可以通过设定特殊权限的方式来为用户支付 CPU/NET 的费用。dApp 方可以设定一个特殊的权限(可称之为免费权限),供任何用户使用。如果用户使用其账号和dApp的该免费权限联合对事务签名,而且将该免费权限放在首位,那么,dApp 方会为与其智能合约交互的用户事务支付 cpu/net 的费用。仅为译者个人理解,有误之处,还请指教)
不过,这一做法有一个缺点: dApp 提供者需要维护自动事务联合签名的服务,使其处于在线状态。这有潜在的成本问题和安全问题。
本提案增加了新的特性: 无需联合签名,合约就可以覆盖事务的成本。合约也可以对资源使用加以限制,避免资源滥用。借助于 查询开销(Query Consumption)
and 主观数据(Subjective Data)这两个提案,合约还能够跟踪事务的资源开销情况。本提案具有 ONLY_BILL_FIRST_AUTHORIZER
这一特性的优势,又不会带来联合签名所造成的问题。
规范
该共识升级特征会增加如下的内嵌函数(intrinsics):
bool accept_charges(
uint32_t max_net_usage_words, // Maximum NET usage to charge
uint32_t max_cpu_usage_ms // Maximum CPU usage to charge
);
void get_accept_charges(
name* contract,
uint32_t* max_net_usage_words,
uint32_t* max_cpu_usage_ms,
);
void get_num_actions(
uint32_t* num_actions,
uint32_t* num_context_free_actions,
);
在一笔事务之中,如果合约是 accept_charges
函数的首个调用方,则事务的开销将会由合约账户承担,直至达到限定的条件。如果事务的开销超过了限定值,则会中断。如果合约账户没有足够的资源,事务也会中断执行。
合约可以多次在一笔或者多笔 action 中调用这一函数;这为合约提供了修改限制的能力。在合约同意付费之后,原先在事务中的 NET 和 CPU 限定就不起作用了。
如果多个合约调用了 accept_charges
,则首个调用者会被收取费用。accept_charges
会返回true给该合约,而返回 false 值给其他的合约。如果首个合约调用了多次该函数,无论是在相同的action还是不同的多个action之中,每次都会返回 true。
get_accept_charges
函数会查询某合约是否会承担费用。如果合约会承担费用,该函数会为参数提供细节信息。如果没有合约承担费用,则会将参数填充为0。
get_num_actions
会返回在初始事务之中非 context-free 类型的操作(action)的数量。该数字不包含任何内联操作。该函数会帮助合约方使其免于支付其他合约的操作,可以查看
合约验证提案(Contract Authentication)之中的使用案例,获得如何进行合约验证的建议。
对延迟事务而言,accept_charges
不会产生作用,返回值始终为false。
合约验证提案(Contract Authentication) 在本提案的基础上为 accept_charges
函数增加了额外的功能。
(译文完,欢迎反馈)
EOS42 期待你的了解和支持
EOS42 为 EOS 主网创世节点之一,账号是 eos42freedom 欢迎为我们投票,表达您的支持。
🍎网站:https://eos42.io
🍋币乎: https://bihu.com/people/365621
🍑Medium: https://medium.com/@eos42
🍏知乎: https://zhuanlan.zhihu.com/eos42
image