WAX链游EOS网络第三方代付CPU资源实现代码

Posted encoderlee

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WAX链游EOS网络第三方代付CPU资源实现代码相关的知识,希望对你有一定的参考价值。

回顾

《【WAX链游】EOS网络第三方代付CPU资源【原理】》
在上一篇文章中,我们介绍了EOS网络的【ONLY_BILL_FIRST_AUTHORIZER】特性,我们知道如何用A账户来支付B账户提交的交易的CPU/NET资源费用。本文,我们讲给出基于【eosjs】【waxjs】【eospy】的示例代码。

EOSJS实现

首先贴出示例代码github仓库地址,所有的示例代码都在这里,有一定基础的同学可以简单看一下就立马上手:

https://github.com/encoderlee/eos_demo

我们的大部分测试用例运行在EOS测试网络【Jungle3.0】之上,这当然也适用于EOS主网和WAX主网,只需修改RPC端点即可。

首先参考:https://github.com/encoderlee/eos_demo/blob/main/eosjs_demo/normal_transfer.html

这是使用eosjs实现的一笔转账交易,我们将 0.0001 个 EOS代币从账号【consumer1111】转给账号【consumer2222】,关键代码如下:

const consumer_name = "consumer1111";
const consumer_private_key = "5KWxgG4rPEXzHnRBaiVRCCE6WAfnqkRpTu1uHzJoQRzixqBB1k3";

const rpc = new eosjs_jsonrpc.JsonRpc("https://jungle3.greymass.com");
const provider = new eosjs_jssig.JsSignatureProvider([consumer_private_key]);
const api = new eosjs_api.Api( rpc:rpc, signatureProvider: provider );

const result = await api.transact(
            actions: [
                account: 'eosio.token',
                name: 'transfer',
                authorization: [
                    
                        actor: consumer_name,
                        permission: "active",
                    ,
                ],
                data: 
                    from: consumer_name,
                    to: "consumer2222",
                    quantity: '0.0001 EOS',
                    memo: 'by eosjs',
                ,
            ]
        , 
            blocksBehind: 3,
            expireSeconds: 90,
        );

代币的转移本质上是调用合约【eosio.token】的【transfer】方法,【data】是传递给【transfer】方法的参数,【authorization】指明该笔交易由谁来签名。正常情况下,这笔交易由【consumer1111】来支付CPU/NET资源费用。

那么根据上文的原理,如果要让第三个账号来支付该笔交易的CPU/NET资源费用,只需在【authorization】中增加第三个账号即可。

参考:https://github.com/encoderlee/eos_demo/blob/main/eosjs_demo/only_bill_first_authorizer.html

关键代码:

const consumer_name = "consumer1111";
const consumer_private_key = "5KWxgG4rPEXzHnRBaiVRCCE6WAfnqkRpTu1uHzJoQRzixqBB1k3";
const payer_name = "payer2222222";
const payer_private_key = "5KAskRRbqYVCRhZxLXqeg9yvWYQQHifDtf7BPceZUDw6zybjaQh";

const rpc = new eosjs_jsonrpc.JsonRpc("https://jungle3.greymass.com");
const provider = new eosjs_jssig.JsSignatureProvider([consumer_private_key, payer_private_key]);
const api = new eosjs_api.Api( rpc:rpc, signatureProvider: provider );

const result = await api.transact(
            actions: [
                account: 'eosio.token',
                name: 'transfer',
                authorization: [
                    
                        actor: payer_name,
                        permission: "active",
                    ,
                    
                        actor: consumer_name,
                        permission: "active",
                    ,
                ],
                data: 
                    from: consumer_name,
                    to: "consumer2222",
                    quantity: '0.0001 EOS',
                    memo: 'by eosjs',
                ,
            ]
        , 
            blocksBehind: 3,
            expireSeconds: 90,
        );

可以看到,我们在【authorization】中增加了【payer2222222】这个账号,并且把【payer2222222】放到了前面,这时他是第一授权人,最后这笔交易的CPU/NET资源费用将会由【payer2222222】来买单。当然,授权人增加了【payer2222222】后,我们也需要提供【payer2222222】的私钥,该笔交易将分别用【consumer1111】和【payer2222222】的私钥进行签名后发送。

执行效果:

https://jungle3.bloks.io/transaction/64f1c43328b6790c7bacdeb06a832bb6d0b918d253a996091b344cc04b6b2a3f

WAXJS实现

有同学就问了,不对呀,如果是自行创建的EOS/WAX原生账号,私钥在自己手上,确实可以直接用EOSJS来这样发起交易,但是我的WAX账号是用【WAX云钱包】注册的呀,私钥不在我手上,托管在WAX云钱包云端,我无法提供私钥呀,该怎么办。

其实不用担心,仔细阅读【eosjs】【waxjs】的代码就会发现,【waxjs】实际上就是在【eosjs】上套了一层壳,【waxjs】其实也是遵循【eosjs】的API规范来开发的,它也实现了一个SignatureProvider,和【eosjs】的JsSignatureProvider不同的是,【eosjs】的JsSignatureProvider是在本地使用私钥直接签名,而【waxjs】实现的SignatureProvider是在浏览器弹出一个授权小窗口,向【WAX云钱包】服务器发送一个HTTP请求来签署交易,感兴趣的同学可以在浏览器抓包研究授权小窗口发送了什么数据,得到的签名是什么样子的,其实都是按照eosjs的数据格式来的,它并没有做复杂的事情。当然,弄清楚原理的同学,完全可以使用python或java等其它语言,直接发送HTTP请求到 https://public-wax-on.wax.io/wam/sign 完成交易签名,这样就可以脱离浏览器环境实现链游脚本,占用更少的系统资源,一台电脑多开更多号。

本质上我们的目的是为一笔交易设置两个授权人,并且用两个授权人的私钥进行签名,那么只要能【签名】就可以了,私钥未必要在我们手上,所以针对【waxjs】的实现代码是这样的:
参考:https://github.com/encoderlee/eos_demo/blob/main/waxjs_demo/only_bill_first_authorizer.html

//waxjs rpc实例,注意需要先login()
const wax = new waxjs.WaxJS(
        rpcEndpoint: 'https://wax.greymass.com',
    );
const payer_name = "fuckpayforit"; //这里改成你支付CPU的账号
const payer_private_key = "这里填写该账号的私钥"

//eosjs rpc实例
const rpc = new eosjs_jsonrpc.JsonRpc('https://wax.greymass.com');
const provider = new eosjs_jssig.JsSignatureProvider([payer_private_key]);
const api = new eosjs_api.Api(rpc: rpc, signatureProvider: provider);

//注意broadcast: false,我们并没有发送交易,只是将交易序列化
let transcation_args = await api.transact(
    actions: [
    account: 'eosio.token',
    name: 'transfer',
    authorization: [
        
            actor: payer_name,
            permission: "active",
        ,
        
            actor: wax.user.account,
            permission: "active",
        ,
    ],
    data: 
        from: wax.user.account,
        to: "consumer1111",
        quantity: '0.00010000 WAX',
        memo: 'by waxjs',
    ,
],
, 
    blocksBehind: 3,
    expireSeconds: 90,
    sign: false,
    broadcast: false,
);

//首先借助eosjs用【fuckpayforit】的私钥签名
let available_keys = await api.signatureProvider.getAvailableKeys();
let sign_args = 
    chainId: api.chainId,
    requiredKeys: available_keys,
    serializedTransaction: transcation_args.serializedTransaction,
;
transcation_args = await api.signatureProvider.sign(sign_args);
const payer_signatures = transcation_args.signatures;

//然后,借助waxjs用登录的wax账号对该笔交易进行签名
available_keys = await wax.api.signatureProvider.getAvailableKeys();
sign_args = 
    chainId: api.chainId,
    requiredKeys: available_keys,
    serializedTransaction: transcation_args.serializedTransaction,
;
transcation_args = await wax.api.signatureProvider.sign(sign_args);

//合并签名
transcation_args.signatures = payer_signatures.concat(transcation_args.signatures)

//最后,发送该笔交易,用eosjs或者用waxjs来发送都行,一样的
const result = await api.pushSignedTransaction(transcation_args);

在上面的代码中,我们用登录的wax账号给【consumer1111】这个账号转账0.0001个WAX,但是该笔交易的CPU/NET费用由【fuckpayforit】来支付。

执行效果:

https://wax.bloks.io/transaction/02a069aac945d62d5a91e913dce7e96862235bc5c382bc7da78b9da088430a62

注意【fuckpayforit】这个账号是我们使用【Anchor】创建的WAX原生账号,私钥在我们手上,并非WAX云钱包账号,而发起交易的账号【m45yy.wam】则是托管的WAX云钱包账号。

以此为例,我们只需要创建一个用于支付CPU/NET资源的账号A,并且质押够足够多的CPU资源,然后我们的几百个WAX云钱包账号用来玩链游,这几百个账号可以完全0质押,在玩游戏,调用智能合约,发送交易的时候,让账号A也来签一下名,就可以实现所有账号的所有操作所需的CPU/NET资源都由账号A来买单。

当然这个买单的账号A也可以是一个WAX云钱包账号,但我觉得没必要了,原生账号更好管理。

EOSPY实现

至于使用Python如何实现,这里不再赘述,直接看代码即可:
https://github.com/encoderlee/eos_demo

参考

关于【ONLY_BILL_FIRST_AUTHORIZER】,这里有其它的一些好的文章和开源项目可以参考:
https://cmichel.io/eosio-how-to-pay-for-users-cpu
https://github.com/MrToph/eos-pay-for-user-cpu-example
https://github.com/pudrikrete/only_bill_first_authorizer
https://github.com/jan-gogogo/only-bill-first-authorizer

开发者涨薪指南 48位大咖的思考法则、工作方式、逻辑体系

以上是关于WAX链游EOS网络第三方代付CPU资源实现代码的主要内容,如果未能解决你的问题,请参考以下文章

WAX链游工作室打金神器EOS网络第三方代付CPU资源实现代码

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

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

WAX链游工作室打金神器EOS网络第三方代付CPU资源原理

区块链Python开发EOS交易机器人WAX链游脚本常用工具

区块链Python开发EOS交易机器人WAX链游脚本常用工具