【WAX链游】EOS网络第三方代付CPU资源【原理】

CPU资源

在之前的文章中,我们尝试用python写了一个链游Farmers World【农民世界】的挂机脚本:
《链游Farmers World【农民世界】爆火,发布一个免费开源的辅助挂机脚本》
https://encoderlee.blog.csdn.net/article/details/121512342
如果你是个人玩家,手上的号比较少,通常不会有太大问题,但如果你是工作室,手上有成百上千账号,则管理起来会非常麻烦,每个账号都需要质押一定的WAX代币以获取CPU/NET资源,而且由于网络拥堵情况经常发生变化,经常出现爆CPU的现象,但是过一段时间,随着网络拥堵情况减少,又可以执行操作了,这是为什么呢?
在这里插入图片描述
我们可以在【Wax Block Explorer】查询我们账户的CPU可用值,隔一段时间去刷新页面,我们可以发现,同样是质押90个WAX不变,但是我们的CPU最大可用值却是不停变化的,实际上这个最大可用值是由用户CPU抵押量、全网用户CPU抵押量以及链上CPU的使用情况决定的,当网络拥堵的时候,我们的CPU最大可用值会减少,如上图所示,有时候可能会减少到小于已用值,这个时候我们的账户就无法执行智能合约操作了,但是过上一段时间,网络开始通畅,我们又有一定的可用值去操作了。这就是为什么脚本在运行过程中,有时候会出现CPU资源不足的情况,但是过上一段时间,又能自行恢复。

需求

你可能会说了,我只要质押足够的多的WAX代币,比如质押1000个WAX,那么就算网络拥堵,我的CPU最大可用值也有可观的余量,而不会出现不够用的情况。但是如果你有上百个上千个账号,究竟每个号质押多少WAX才算够用呢?质押多了,占用资金,并且需要承担更多WAX币价下跌的风险,质押少了,到时候不够用又来临时增加质押,会变得非常麻烦。而且解除质押赎回WAX需要等待3天,很难根据情况动态的增加或减少WAX的质押量。

那么,我们是不是可以考虑,假如我们的几百个WAX账号,都不质押CPU/NET,也就是除了创建账号必须购买少量RAM之外,我们每个账号都质押0个WAX行不行呢?然后我们用一个WAX账号来集中为这几百个WAX账号的交易支付CPU/NET资源行不行呢?这样管理起来也方便,我们只需要在这个【资源代付者】的账号上质押足够多的WAX,比如5000个,1万个,然后其他几百个小号都是0质押,这几百个小号需要调用智能合约,需要挖田种地养牛羊鸡的时候,每一笔交易都让【资源代付者】来支付CPU/NET资源就好了。而且,由于我们的几百个小号一般不会同时去进行操作,这样能错开网络最拥堵的时间点,在最拥堵的时候,我们的大号【资源代付者】都有足够的余量来完成单个账号的单笔交易操作。

可能这个需求对于Farmers World【农民世界】来说并不是刚需,但对于我们的其它几款WAX链游脚本,比如【Alien Worlds】来说则显得尤为重要,因为【Alien Worlds】需要频繁的挖矿操作,如果管理上百个账号则需要发送大量的交易,将资源的支付归集到一个账号好,有非常多的好处。

资源代付

CPU/NET资源代付实际上是借助了EOSIO1.8引入的一个【ONLY_BILL_FIRST_AUTHORIZER】特性,目前WAX主网版本为2.0以上,自然早已支持这个特性。

这个特性允许将一笔交易的CPU/NET成本计入第一个授权账号,这样使得一个帐户可以支付另一个账户交易所需的 CPU 成本,简单来说就是A账户发送交易(调用智能合约),由B账户来支付这笔交易的CPU/NET资源。

这个特性设计的主要目的,是为了允许dapp开发者为其用户的 CPU/NET付费,实际上【Farmers World】【Alien Worlds】项目方都使用了这个特性,为它们的玩家支付了一些CPU成本。

TokenPocket钱包的【顺畅模式】其实也是通过这一特性实现的。

【Alien Worlds】为例,我们知道每个新建的账号即使质押WAX为0,没有任何CPU资源,我们也可以免费挖上几十次。那么这是如何实现的呢?
在这里插入图片描述https://wax.bloks.io/transaction/f7b9bca36f8ef2b10cfe9f6c80658e673438668c40cfa28abda6096d8c5ea048

以这笔交易为例,我们的账号【cjemk.c.wam】从始至终CPU质押均为0,那么这笔交易是如何发起的呢?

可以注意到,这笔交易有两个action,其中第一个action调用的是【yeomenwarder】合约的【warder】方法,授权人是【yeomenwarder】,那么这笔交易消耗的378us的CPU资源以及192Bytes资源,就由【yeomenwarder】这个账号来买单。

所以简单来说,就是一笔交易的所需的CPU/NET资源,由这笔交易的第一个action的第一个授权人来买单。

当然,如果一笔交易只有一个action,那么就由第一个授权人来买单。
在这里插入图片描述

https://wax.bloks.io/transaction/02a069aac945d62d5a91e913dce7e96862235bc5c382bc7da78b9da088430a62
比如这笔交易,【m45yy.wam】给【consumer1111】发起一笔转账交易,但是由【fuckpayforit】来支付这笔交易的CPU/NET费用,因为【fuckpayforit】是第一授权人。

设计初衷

【ONLY_BILL_FIRST_AUTHORIZER】特性的设计初衷,主要是为了允许dapp开发者为其用户的 CPU/NET付费,允许第三方服务商为其用户支付CPU/NET资源。

比如我们开发了一个EOS应用,为了吸引更多用户来使用,我们在我们的账号上质押了大量的WAX,只要玩家和我们的dapp交互,我们就可以在一定的限度内为其支付CPU/NET资源。

实际上,WAX云钱包为用户每24小时内最多提供5ms的CPU资源和5k的NET带宽,就是通过这个特性来实现的。
在这里插入图片描述
https://wax.bloks.io/transaction/ea420cf3b95ee521b6ba70c1d539b7202e677bef8dcb84912411434e68958127

比如这笔交易,其实用户【1vvtk.wam】提交的原始交易只有一个action,就是调用【dungeonitems】合约的【equip】方法,但是在使用waxjs提交交易的时候,默认参数freeBandwidth = true,wax wallet会根据情况给这笔交易加上一个action,即调用【boost.wax】合约的【noop】方法,然后boost.wax使用自己一个权限比较低的私钥【paybw】为这笔交易授权,所以这笔交易消耗的CPU/NET资源最终由【boost.wax】来买单。

实际上【boost.wax】合约的【noop】方法是一个空函数,什么也不做。那么为什么waxjs要增加一个action去调用一个什么都不干的方法【noop】呢?那是出于安全考虑,项目方为了帮你支付这笔交易的CPU费用,需要用项目方的私钥为你的这笔交易签名,且把自己列为第一授权,如果项目方盲目的为你的【dungeonitems - equip】这个action签名的话,容易造成一些安全问题,谁知道你的【dungeonitems - equip】这个动作做了什么呢?所以项目方需要增加一个无害且无用的【noop】操作,并且项目方的私钥只对这个它认可的【noop】操作进行签名,并且把这个action放到前面,这样【boost.wax】就成了这笔交易的第一授权人,即实现了为该笔交易支付CPU资源,也保证了自身安全。

当然,我们的需求不一样,我们不需要给不信任的账户交易进行签名,我们的需求是用自己的A账号给自己的B/C/D/E一大堆小号的交易进行签名,为它们支付CPU/NET费用,所有号都是我们自己的,所有私钥都在我们手里,所以我们无需担心安全问题,自然也就不需要【noop】操作,【noop】操作虽然是空函数,但多多少少也会增加CPU资源占用。

在这里插入图片描述
所以最终我们只需要这样就行了,B账号创建交易,用A/B账号的私钥对交易进行签名,且把A账号作为第一授权人放在签名,提交交易后,就由A账号来支付CPU/NET资源费用。

实现代码

好,此致原理我们已经完全了解,接下来,如何在代码中使用【ONLY_BILL_FIRST_AUTHORIZER】特性呢,我们在下一篇文章中将给出基于【eosjs】【waxjs】【eospy】的示例代码

【WAX链游】EOS网络第三方代付CPU资源【实现代码】
https://encoderlee.blog.csdn.net/article/details/123062657

猜你喜欢

转载自blog.csdn.net/CharlesSimonyi/article/details/123059794