怎样自动归集用户充值的ETH或者usdt到归集地址并最优化归集交易gas费

  • A+
所属分类:币安BSC
摘要

在dapp开发过程中经常会遇到ETH,BNB,Matic,ARB,OP,USDT等代币充值后自动归集的问题。充值WETH和USDT的归集方式是不同的,虽然都得采用特定的充提币接口。主要因为每个公链都可以自动识别本链上的WETH主币,但是却不能识别其他ERC20代币,比如USDT作为ERC20代币如果直接充值到充币接口中是不能被合约识别并自动归集的。


chatGPT账号

一、说明

在dapp开发过程中经常会遇到ETH,BNB,Matic,ARB,OP,USDT等代币充值后自动归集的问题。充值WETH和USDT的归集方式是不同的,虽然都得采用特定的充提币接口。主要因为每个公链都可以自动识别本链上的WETH主币,但是却不能识别其他ERC20代币,比如USDT作为ERC20代币如果直接充值到充币接口中是不能被合约识别并自动归集的。

dapp充币接口设计主要考虑三方面的因素:

  1.  用户通过充币接口完成WETH或者USDT的充值后,需要自动实时的归集到归集钱包地址,并且最大可能的降低归集gas费用。
  2. 用户直接向合约地址充值WETH或者usdt后,dapp需要能正常识别出每个地址的充值数量,然后将充值金额同步链上数据保存到数据库中。
  3. WETH或者usdt充值和归集两个步骤最大化的降低交易gas费用。同时,避免小额gas费用残留问题。

怎样自动归集用户充值的ETH或者usdt到归集地址并最优化归集交易gas费

二、充提币及自动归集接口合约代码实现方式

针对每个公链上的主币WETH和ERC20代币,充提币及自动归集接口实现方式是不同的。充币及自动归集接口相对要简单,提币接口需要根据所属公链的要求以及dapp程序设置中的业务要求确定采用的实现方式,常规的提币接口为签名验签withdraw和直接claim赎回方式。

1. 充值ERC20(USDT为例)及自动归集的接口实现方式源码:

function collect(address collector, uint256 collCount) external onlyOwner returns (bool, address, uint256) {
        require(isCollector(collector), "COLL: invalid collector"); 
        
        address collAdr = collector;
        uint256 collNum = collCount;
        uint256 tokenBalance = BUSD.balanceOf(collAdr);
        if(collNum > tokenBalance) {
            collNum = tokenBalance;
        }
        if (tokenBalance > 0) {
            BUSD.transferFrom(collAdr, rec, collNum);
            historyReceords.push(Receord({depositer: collAdr, amount: collNum}));
            uint256 counter = historyReceords.length - 1;
            indexs[collAdr].push(counter);
        }

        emit Collect(collAdr, collNum);

        return(true, collAdr, collNum);
    }

    function collectAll(address collector) external onlyOwner returns (bool, address, uint256) {
        require(isCollector(collector), "COLL: invalid collector"); 
        
        address collAdr = collector;
        uint256 tokenBalance = BUSD.balanceOf(collAdr);
        if (tokenBalance > 0) {
            BUSD.transferFrom(collAdr, rec, tokenBalance);
            historyReceords.push(Receord({depositer: collAdr, amount: tokenBalance}));
            uint256 counter = historyReceords.length - 1;
            indexs[collAdr].push(counter);
        }

        emit CollectAll(collAdr, tokenBalance);

        return(true, collAdr, tokenBalance);
    }

2. 签名验签方式的提币接口实现代码如下:

function withdraw(
        uint256 amount,
        address to,
        uint256 nonce,
        bytes memory signature
) external {
        require(nonce > userNonce[to], "nonce");
        require(
            verify(signer, amount, to, nonce, signature),
            "signature not match"
        );

        record[to] = UserWithdraw({
            amount: amount + record[to].amount,
            lastRewardTime: block.timestamp
        });
        userNonce[to] = nonce + 1;
        DWT.transfer(to, amount);

        emit Withdraw(address(this), to, amount, block.timestamp);
        
    }

由dapp前端使用系统钱包私钥对提币数据进行签名,将签名消息发送到链端,由链端对签名消息进行verify拆分出签名的公钥地址,最终验证签名的公钥地址为系统内置钱包地址,说明提币请求是来自于dapp的合法提币请求,而不是非法的模拟提币请求。

3. 通过claim方式统一将充提币数据完全交由链端处理的实现方式:

function claim(address currency,uint256 _amount) public { 
        require(tokenAmount[currency][msg.sender] >= _amount, "Claim: not balance");
        require(claimFrozen[msg.sender] ==0, "Claim: userAmount must > 0");     
        Config memory config  =configMap[currency];
        require(config.minAmount <= _amount&&config.maxAmount >= _amount, "Claim: _amount error!");
        require(config.status==0, "Claim: status is error!");
        uint256 fee=0;
        uint256 reserveAmount=0;
        if(currency==WETH){
            reserveAmount= SafeMath.div(SafeMath.mul(_amount,MineDetail[withdrawRate[msg.sender]].rate),100);
            uint256 amount=SafeMath.sub(_amount,reserveAmount);
            fee =SafeMath.div(SafeMath.mul(amount,config.fee),100);
            uint256 realamount=SafeMath.sub(amount,fee);
            safeTransferETH(msg.sender, realamount);
        }else{
            fee =SafeMath.div(SafeMath.mul(_amount,config.fee),100);
            uint256 realamount=SafeMath.sub(_amount,fee);
            safeTransferToken(currency,address(msg.sender), realamount);
        }
        tokenAmount[currency][msg.sender] = tokenAmount[currency][msg.sender].sub(_amount);
        emit Claim(currency,msg.sender, _amount,reserveAmount,fee);
    }

该方式支持WETH,ERC20(usdt)方式任意代币的充提要求。完全由链端处理代币的充提,dapp所有数据都需要实时的与链端进行同步保存到数据库中。该种方式虽然有限的规避了签名验签带来的繁琐校验要求,却增加了本地dapp数据库与链端数据频繁同步的业务负载。

三、WETH及USDT充币接口自动归集降低gas费用的几种实现方式

方法1. ETH 由充值的人支付归集矿工费,交易平台完全不用花矿工费

如图一的简图,藉由智能合约中的fallback 功能,让所有充值到合约地址上的ETH 自动转移到指定地址,也就是由充值的客户来支付矿工费的意思,在这个方法中,我们需要给每个用户部署一个智能合约,智能合约地址就是用户的充值地址,所有打进这个地址的交易,都会自动触发转帐到另一个钱包。由于充值跟归帐的行为是在一次交易中发生的,因此在一笔交易中,我们就完成了充值跟归集,矿工费会由发起充值交易的对象来支付。

图一

怎样自动归集用户充值的ETH或者usdt到归集地址并最优化归集交易gas费

方法2. ERC20 代币合约中提供ABI,让呼叫者支付归帐矿工费,节省水池打燃料给充值地址的矿工费,同时避免小额燃料费残留问题

ETH 代币中最知名的ERC20 代币当属USDT,参考USDT-ERC20 合约地址可以看到USDT-ERC20 的所有交易,由于USDT 的交易其实是对发行USDT 的合约进行交易,在交易中会让USDT合约把登记在合约中A 地址的USDT 转移登记到B 地址底下,这是合约里的固定行为,在无法修改合约内容的情况下,我们无法像第一个方法中,让充值的人支付归集矿工费。

怎样自动归集用户充值的ETH或者usdt到归集地址并最优化归集交易gas费

方法3. ETH 或ERC20 代币可自动化设定矿工费低点进行归帐

由于不是每个人都知道怎么撰写智能合约,同时部署智能合约也需要成本,因此针对ETH 原生地址,你也可以使用一些方法来节省矿工费,如果将ETH 矿工费历史纪录翻开,可以发现即便是矿工费最高(500-600 gwei) 的那段时间,每天或每周都会有一两个时段,矿工费会维持低档一段时间,因为交易毕竟是人在进行的,很多时候进入休息时段,交易没这么热络就会出现矿工费降低的空挡,因此设定好你的矿工费上限,超过上限就暂时不要交易,当矿工费低于上限一段时间就赶紧归帐吧!

怎样自动归集用户充值的ETH或者usdt到归集地址并最优化归集交易gas费

方法4. 利用ERC20 合约标准接口的approve 跟transferFrom ABI,节省水池打燃料给充值地址的矿工费,同时避免小额燃料费残留问题

由于ERC20 合约都提供有approve 及tansferFrom 两个ABI,善用这两个ABI 就能够让每次归集ERC20 代币时,免去从水池打矿工费给归帐地址的那笔交易费用,直接呼叫transferFrom 进行归帐,也免去会有小额燃料费没有用完又不想回收的问题。

方法5. BTC/LTC 等UTXO 类型的币种,可以将充值跟提币钱包合并,不做归集,直接使用用户充值的多个UTXO 组合,满足客户的提币请求

对于UTXO 类型的币种如BTC / LTC / BCH / BSV / DASH / DOGE 等币种,由于币种本身支援multi-in & multi-out,客户充值在不同地址的资产就能够合并使用,比如有三个客户分别充值了0.1、0.3、0.06 BTC,当你需要进行一笔提币金额是0.35 BTC,系统就可以直接拿出0.1 跟0.3 BTC 组合成一笔交易提出,省掉了归集的过程,当然,因为提币钱包跟充值钱包合并了,资安风险自然会增加,用户在创建这种类型的钱包时务必要注意安全风险,进行风控降低风险系数。

方法6. USDT-Omni 由归帐地址支付矿工费,节省水池打燃料给充值地址的矿工费,同时还可以用上USDT-Omni 交易中小额的Dust

最后则是USDT-Omni 归帐的方式,由于USDT-Omni 交易时,交易中都会带上一个0.00000546 或0.0000054 BTC 的Dust,这笔如灰尘般的BTC 实在让人想收下也不是,不收下一直放在那也碍眼,此外当要归集USDT-Omni 时,也必须打一笔矿工费进到这个地址才能进行归帐,在Omni 的协议中其实是允许对方帮他付款的,因此利用Omni 协议中的这项功能,就不用先把矿工费打给归帐地址,而是可以直接进行归帐,由归帐地址直接支付矿工费,同时把USDT-Omni 当初充值时小额的Dust 作为Input 来产生一笔Dust 的Output。

至此,完成怎样自动归集用户充值的ETH或者usdt到归集地址并最优化归集交易gas费所有操作流程。

pdf+视频币安智能链BSC发币教程及多模式组合合约源代码下载:

币安智能链BSC发币(合约部署、开源、锁仓、LP、参数配置、开发、故障处理、工具使用)教程下载:

怎样自动归集用户充值的ETH或者usdt到归集地址并最优化归集交易gas费怎样自动归集用户充值的ETH或者usdt到归集地址并最优化归集交易gas费怎样自动归集用户充值的ETH或者usdt到归集地址并最优化归集交易gas费怎样自动归集用户充值的ETH或者usdt到归集地址并最优化归集交易gas费怎样自动归集用户充值的ETH或者usdt到归集地址并最优化归集交易gas费

多模式(燃烧、回流指定营销地址、分红本币及任意币种,邀请推广八代收益,LP加池分红、交易分红、复利分红、NFT分红、自动筑池、动态手续费、定时开盘、回购)组合合约源代码下载:

怎样自动归集用户充值的ETH或者usdt到归集地址并最优化归集交易gas费怎样自动归集用户充值的ETH或者usdt到归集地址并最优化归集交易gas费

pdf+视频币安智能链BSC发币教程及多模式组合合约源代码下载地址:

此处为隐藏的内容!
登录后才能查看!

添加VX或者telegram获取全程线上免费指导

怎样自动归集用户充值的ETH或者usdt到归集地址并最优化归集交易gas费
免责声明

免责声明:

本文不代表知点网立场,且不构成投资建议,请谨慎对待。用户由此造成的损失由用户自行承担,与知点网没有任何关系;

知点网不对网站所发布内容的准确性,真实性等任何方面做任何形式的承诺和保障;

网站内所有涉及到的区块链(衍生)项目,知点网对项目的真实性,准确性等任何方面均不做任何形式的承诺和保障;

网站内所有涉及到的区块链(衍生)项目,知点网不对其构成任何投资建议,用户由此造成的损失由用户自行承担,与知点网没有任何关系;

知点区块链研究院声明:知点区块链研究院内容由知点网发布,部分来源于互联网和行业分析师投稿收录,内容为知点区块链研究院加盟专职分析师独立观点,不代表知点网立场。

 

本文是全系列中第248 / 255篇:行业技术

  • 我的微信
  • 这是我的微信扫一扫
  • weinxin
  • 我的电报
  • 这是我的电报扫一扫
  • weinxin
chatGPT账号
知点

发表评论

您必须登录才能发表评论!