以太坊智能合约实现批量转账(空投)可转代币或者以太币
作者:互联网
现成工具:CoinTool.App
参考资料
使用智能合约转代币是比较容易理解的,上面的链接中基本都有,直接拿来可以用。
但是转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发布一条带地址的推文
流程,
-
首先去创建一个钱包地址
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");
标签:function,可转,以太,tos,代币,value,let,address,eth 来源: https://blog.csdn.net/qq_23341623/article/details/113341459