以太坊智能合约实现批量转账(空投)可转代币或者以太币

参考资料

solidity .批量转账,存入eth

以太坊合约实现批量转账(空投)原理解析  

以太坊智能合约之批量转币

专门用于批量空投的 ETH 智能合约(该链接需要梯子)

教你一招 如何批量发送eth 或者代币

使用智能合约转代币是比较容易理解的,上面的链接中基本都有,直接拿来可以用。

但是转eth就有点蒙了。 上面就最后一个链接给了代码,网上查了好几个地方都是那个代码,然后再remix中部署,却没用- -

单单弄这个批量转eth搞了好几天!!!

说明:上面那个代码实际是有用的,不过是我开始对概念不够懂..! 上面代码实际是通过智能合约来转币,也就是说,需要智能合约中有eth,才能调用_to.transfer(msg.value); 否则,都没币,怎么转!

之后又纠结于,如何给智能合约地址转币...  如果通过其他方式转给智能合约eth,然后再调用智能合约的批量方法,这就是两个步骤了,显然达不到要求...

又纠结了大半天, 最后在一个群友的提示下, 突然想到了remix编辑器右上角有个value...  代码转币的时候也是有个value(转代币的时候都是填0x0;

好了,废话了好多...

下面发直接能用的代码

合约工具代码

pragma solidity ^0.4.24;
contract TransferTool {

    address owner = 0x0;
    function TransferTool () public  payable{//添加payable,支持在创建合约的时候,value往合约里面传eth
        owner = msg.sender;
    }
    //批量转账
         function transferEthsAvg(address[] _tos) payable public returns (bool) {//添加payable,支持在调用方法的时候,value往合约里面传eth,注意该value最终平分发给所有账户
                require(_tos.length > 0);
                require(msg.sender == owner);
                var vv = this.balance/_tos.length;
                for(uint32 i=0;i<_tos.length;i++){
                   _tos[i].transfer(vv);
                }
             return true;
         }
         function transferEths(address[] _tos,uint256[] values) payable public returns (bool) {//添加payable,支持在调用方法的时候,value往合约里面传eth,注意该value最终平分发给所有账户
                require(_tos.length > 0);
                require(msg.sender == owner);
                for(uint32 i=0;i<_tos.length;i++){
                   _tos[i].transfer(values[i]);
                }
             return true;
         }
         //直接转账
         function transferEth(address _to) payable public returns (bool){
                require(_to != address(0));
                require(msg.sender == owner);
                _to.transfer(msg.value);
                return true;
         }
         function checkBalance() public view returns (uint) {
             return address(this).balance;
         }
        function () payable public {//添加payable,用于直接往合约地址转eth,如使用metaMask往合约转账
        }
        function destroy() public {
            require(msg.sender == owner);
            selfdestruct(msg.sender);
         }

    function transferTokensAvg(address from,address caddress,address[] _tos,uint v)public returns (bool){
        require(_tos.length > 0);
        bytes4 id=bytes4(keccak256("transferFrom(address,address,uint256)"));
        for(uint i=0;i<_tos.length;i++){
            caddress.call(id,from,_tos[i],v);
        }
        return true;
    }
      function transferTokens(address from,address caddress,address[] _tos,uint[] values)public returns (bool){
        require(_tos.length > 0);
        require(values.length > 0);
        require(values.length == _tos.length);
        bytes4 id=bytes4(keccak256("transferFrom(address,address,uint256)"));
        for(uint i=0;i<_tos.length;i++){
            caddress.call(id,from,_tos[i],values[i]);
        }
        return true;
    }
}

测试结果图

node代码

批量转代币,代码里面的x,自行修改成自己对应的地址参数 

(注意,转代币需要先调用approve授权,)

    let contract = new ConfigInit.getWeb3().eth.Contract(TOOLabi, TOOLaddr);
    let destAddr = 'x';
    let tos = ["x", "x"];
    let value = ConfigInit.getWeb3().utils.toWei('26.2');
    let from = 'x';
    let pData = contract.methods.transfer(from,destAddr,tos,value).encodeABI();
    let prikey = 'x';
    TransferUtils.sendTokenOptions(from, prikey, TOOLaddr, '0x0', TOOLaddr, pData).then(function (hash) {
        console.log('------------- ' + hash);
    }).catch(function (e) {
        console.log('------------- ' + e.message);
    });
    res.send('===========');

批量转eth

router.get('/mulSendEth',function (req,res,next) {
    let contract = new ConfigInit.getWeb3().eth.Contract(ETHTOOLabi, ETHTOOLaddr);
    let tos = ["x","x","x","x"];
    let web3 = ConfigInit.getWeb3();
    let value = web3.utils.toWei('1');
    let from = 'x';
    let prikey = 'x';
    let pData = contract.methods.transferETHS(tos).encodeABI();
    let strvalue = web3.utils.toHex(value);
    TransferUtils.sendTokenOptions(from, prikey, ETHTOOLaddr, strvalue, ETHTOOLaddr, pData).then(function (hash) {
        console.log('------------- ' + hash);
    }).catch(function (e) {
        console.log('------------- ' + e.message);
    });
    res.send('===========');
});
router.get('/mulSendEth2',function (req,res,next) {
    let contract = new ConfigInit.getWeb3().eth.Contract(ETHTOOLabi, ETHTOOLaddr);
    let tos = ["x","x","x","x"];
    let tovalue = ["400000000000000000","100000000000000000","350000000000000000","150000000000000000"];
    let web3 = ConfigInit.getWeb3();
    let value = web3.utils.toWei('1');
    let from = 'x';
    let prikey = 'x';
    let pData = contract.methods.transferETHS(tos,tovalue).encodeABI();
    let strvalue = web3.utils.toHex(value);
    TransferUtils.sendTokenOptions(from, prikey, ETHTOOLaddr, strvalue, ETHTOOLaddr, pData).then(function (hash) {
        console.log('------------- ' + hash);
    }).catch(function (e) {
        console.log('------------- ' + e.message);
    });
    res.send('===========');
});
sendTokenOptions 里面实际是
function sendTranscation(tr, fromAddr, privatekey, to, value, data, nonce, gasLimit, gasPrice) {
    let rawTransaction = {
        from: fromAddr,
        to: to,
        value: value,
        gasLimit: toHex(gasLimit),
        gasPrice: toHex(gasPrice),
        data: data,
        nonce: nonce
    };
    let transaction = new Etx(rawTransaction);
    if (privatekey.startsWith('0x')) {
        privatekey = privatekey.substring(2);
    }
    transaction.sign(Buffer.from(privatekey, 'hex'));
    let serializedTx = transaction.serialize();
    console.log('0x' + serializedTx.toString('hex'));
    return new Promise(function (resolve, reject) {
        let nhash = '';
        console.log('sendsignedTransaction--- ');
        ConfigInit.getWeb3().eth.sendSignedTransaction('0x' + serializedTx.toString('hex')).on('transactionHash', function (hash) {
   
   

顺便提一下如何使用测试节点。

https://www.rinkeby.io/#faucet

通过fb,或者twitter发布一条带地址的推文

流程,

  1. 首先去创建一个钱包地址
    https://vintage.myetherwallet.com/ 注意右上角,选择rinkeby(etherscan.io

  2.发推文 推荐使用twitter; fb特么的不知道怎么获取单条信息的链接..浪费半天时间, 推文内容需要带上面创建的地址     如类似  https://twitter.com/xxxx/status/113300000000000

3.将上面地址填入https://www.rinkeby.io/#faucet输入框, 一会就eth到账。

4.

可以自己搭节点,切换测试节点, 这点不熟。网上找了个...使用infura提供的节点
https://rinkeby.infura.io
可以查询到刚才的钱包地址有余额
web = new Web3("https://rinkeby.infura.io");

猜你喜欢

转载自blog.csdn.net/zgf1991/article/details/90756619