ERC20代币批量转账接口教程

    2020-04-25 16:33:24 #ERC20转账接口 #ERC20接口 #ERC20代币转账接口

    BTC或许是加密数字货币之王,但ETH也有着自己最友善的头衔——最受欢迎数字代币平台。ETH作为一个公共区块链平台,具备着开源的智能合约功能,许多的代币发行通过ETH进行,而代币常见的是ETH上一个遵守着ERC20规范的智能合约。



    假如一个ETH智能合约能够实现下面的接口,那此智能合约就是一个ERC20代币。

     

    // ----------------------------------------------------------------------------

    // ERC Token Standard #20 Interface

    // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md

    // ----------------------------------------------------------------------------

    contract ERC20Interface {

        function totalSupply() public constant returns (uint);

        function balanceOf(address tokenOwner) public constant returns (uint balance);

        function allowance(address tokenOwner, address spender) public constant returns (uint remaining);

        function transfer(address to, uint tokens) public returns (bool success);

        function approve(address spender, uint tokens) public returns (bool success);

        function transferFrom(address from, address to, uint tokens) public returns (bool success);

     

        event Transfer(address indexed from, address indexed to, uint tokens);

        event Approval(address indexed tokenOwner, address indexed spender, uint tokens);

    }

     

    显而易见的是,ERC20规范里仅仅存在点对点转账的transfer和transferFrom,现实情况下可能存在要向1000-10000个地址转账的情况,那我们就要生成上万个transfer交易,不得不考虑这样的效率太低了

     

    因此许多ERC20代币都能够实现批量转账的接口。

    例如一则爆出漏洞的BEC(https://etherscan.io/address/0xc5d105e63711398af9bbff092d4b6769c82f793d#code)实现了batchTransfer函数。

     

    SMT(https://etherscan.io/address/0x55f93985431fc9304077687a35a1ba103dc1e081#code)也实现了allocateTokens函数。

     

    上述这些能够实现一笔ETH交易完成对多个账户的代币转账或初始化的场景

     

    文章中提及了一种完成一对多转账的方法,这个方法被称之为transferMultiple

     

    第一步文中里默认已用SafeMath库

     

    然后,transferMultiple

    transferMultiple完成了从msg.sender向count个_tos地址转账的场景同时_tos[i]得到_values[i]的代币。

     

    首先,进行对于1个for循环前置检查,从而保证每个_tos地址都非0地址,另外还需要计算转账的总额,并将其录入到total变量。在运算操作时,为避免溢出,可以采用SafeMath库,值得注意的是,每一次都要当前计算出来的总额total和上一笔总额total_prev进行对比从而保证total大于等于total_prev,双重校验不会整数溢出避免导致出现转账故障的情况

     

    其次,对于2个for循环采用修改内部变量,但不调用transfer方法原因在于之前已经做了前置检查,倘若再调用transfer函数的话,程序会执行额外的没有必要的前置检查,这样gas增加消耗。

     

    function transferMultiple(address[] _tos, uint256[] _values, uint count)  payable public returns (bool success) {

            uint256 total = 0;

            uint256 total_prev = 0;

            uint i = 0;

     

            for(i=0;i<count;i++){ require(_tos[i]="" !="address(0));" total_prev="total;" total="SafeMath.add(total," _values[i]);="" require(total="">= total_prev);

            }

     

            require(total <= balanceOf(msg.sender);

     

            for(i=0;i<=count-1;i++){

                balances[msg.sender] = SafeMath.sub(balances[msg.sender], _values[i]);

                balances[_tos[i]] = SafeMath.add(balances[_tos[i]], _values[i]);

                Transfer(msg.sender, _tos[i], _values[i]);

                //上面的3可改为下1行,它的优点在于无需假设用户剩余资产存储在类型为mapping的balances这个变量中,它的劣势是会额外增加一些没有必要的前置检查,导致额外消耗gas

                //transfer(_tos[i], _values[i]);

            }

     

            return true;

        }

    此时,相信各位比较在意的是,用transferMultiple一次完成110000转账能否成功?

    测试可以显示140转账的情况下,消耗的gas大致在130万上下如果ETH一个区块的gas上限大为800万,那么,1完成1240转账就将区块的gas上限占满了。假如出现单次转账的收款对象数量太多的情况也会出现超出区块gas上限而致使双方交易无法完成的结果基于以上的问题,在遇到优盾钱包这个开放平台后,我果断放弃了之前的研究,通过API直接对接交易所,免节点同步,便捷又省心。


    相关文章:

    1、BTC bitcoin-cli转账及交易的API使用教程

    2、区块链交易所钱包添币指南!

    3、答疑笔记 | 这10类区块链钱包问题,业内人士最关注

    4、区块链交易所钱包实现原理揭秘!

    在線客服

    申請試用

    申請試用

    設置