完整ERC20批量转账教程

完整ERC20批量转账教程

适合新手:使用该教程,需要对eth智能合约有个基本了解(主要是供自己使用)

代币批量转账注意点(仅测试使用):

http://remix.ethereum.org

1.代币合约使用5.10编译器,批量转账合约使用4.22合约

2.environment使用本地:javaScript VM , 使用本地测试网络不能很好的兼容拜占庭(测试失败)。

3.需要调用approve函数对合约地址进行授权(授权其可以转账代币数量,方可进行批量转账)

4.参数:
4.1代币合约中approve在浏览器上调试的参数:_spender:批量转账合约地址,_value:授权金额
4.2批量转账合约中multisend函数:_tokenAddr:代币合约地址,dests:[“接收地址1”,“接收地址2”],values:[转账金额1,转账金额2]

代币合约:

`
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.22 <0.6.0;
contract owned {
address public owner;
constructor() public {
owner = msg.sender;
}
modifier onlyOwner {
require(msg.sender == owner);
_;
}
function transferOwnership(address newOwner) onlyOwner public {
owner = newOwner;
}
}
interface tokenRecipient { function receiveApproval(address _from, uint256 _value, address _token, bytes calldata _extraData) external; }
contract TokenERC20 {
// Public variables of the token
string public name;
string public symbol;
uint8 public decimals = 18;
// 18 decimals is the strongly suggested default, avoid changing it
uint256 public totalSupply;
// This creates an array with all balances
mapping (address => uint256) public balanceOf;
mapping (address => mapping (address => uint256)) public allowance;
// This generates a public event on the blockchain that will notify clients
event Transfer(address indexed from, address indexed to, uint256 value);
// This generates a public event on the blockchain that will notify clients
event Approval(address indexed _owner, address indexed _spender, uint256 _value);
// This notifies clients about the amount burnt
event Burn(address indexed from, uint256 value);
// constructor(
// uint256 initialSupply,
// string memory tokenName,
// string memory tokenSymbol
// ) public {
// totalSupply = initialSupply * 10 ** uint256(decimals); // Update total supply with the decimal amount
// balanceOf[msg.sender] = totalSupply; // Give the creator all initial tokens
// name = tokenName; // Set the name for display purposes
// symbol = tokenSymbol; // Set the symbol for display purposes
// }
constructor(
) public {
totalSupply = 123456789 * 10 ** uint256(decimals); // Update total supply with the decimal amount
balanceOf[msg.sender] = totalSupply; // Give the creator all initial tokens
name = “invetest”; // Set the name for display purposes
symbol = “it”; // Set the symbol for display purposes
}
function _transfer(address _from, address _to, uint _value) internal {
// Prevent transfer to 0x0 address. Use burn() instead
require(_to != address(0x0));
// Check if the sender has enough
require(balanceOf[_from] >= _value);
// Check for overflows
require(balanceOf[_to] + _value > balanceOf[_to]);
// Save this for an assertion in the future
uint previousBalances = balanceOf[_from] + balanceOf[_to];
// Subtract from the sender
balanceOf[_from] -= _value;
// Add the same to the recipient
balanceOf[_to] += _value;
emit Transfer(_from, _to, _value);
// Asserts are used to use static analysis to find bugs in your code. They should never fail
assert(balanceOf[_from] + balanceOf[_to] == previousBalances);
}
function transfer(address _to, uint256 _value) public returns (bool success) {
_transfer(msg.sender, _to, _value);
return true;
}
function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) {
require(_value <= allowance[_from][msg.sender]); // Check allowance
allowance[_from][msg.sender] -= _value;
_transfer(_from, _to, _value);
return true;
}
function approve(address _spender, uint256 _value) public
returns (bool success) {
allowance[msg.sender][_spender] = _value;
emit Approval(msg.sender, _spender, _value);
return true;
}
function approveAndCall(address _spender, uint256 _value, bytes memory _extraData)
public
returns (bool success) {
tokenRecipient spender = tokenRecipient(_spender);
if (approve(_spender, _value)) {
spender.receiveApproval(msg.sender, _value, address(this), _extraData);
return true;
}
}
function burn(uint256 _value) public returns (bool success) {
require(balanceOf[msg.sender] >= _value); // Check if the sender has enough
balanceOf[msg.sender] -= _value; // Subtract from the sender
totalSupply -= _value; // Updates totalSupply
emit Burn(msg.sender, _value);
return true;
}
function burnFrom(address _from, uint256 _value) public returns (bool success) {
require(balanceOf[_from] >= _value); // Check if the targeted balance is enough
require(_value <= allowance[_from][msg.sender]); // Check allowance
balanceOf[_from] -= _value; // Subtract from the targeted balance
allowance[_from][msg.sender] -= _value; // Subtract from the sender’s allowance
totalSupply -= _value; // Update totalSupply
emit Burn(_from, _value);
return true;
}
}
contract MyAdvancedToken is owned, TokenERC20 {
uint256 public sellPrice;
uint256 public buyPrice;
mapping (address => bool) public frozenAccount;
/* This generates a public event on the blockchain that will notify clients /
event FrozenFunds(address target, bool frozen);
/ Initializes contract with initial supply tokens to the creator of the contract /
constructor(
) TokenERC20() public {}
// constructor(
// uint256 initialSupply,
// string memory tokenName,
// string memory tokenSymbol
// ) TokenERC20(initialSupply, tokenName, tokenSymbol) public {}
/ Internal transfer, only can be called by this contract */
function _transfer(address _from, address _to, uint _value) internal {
require (_to != address(0x0)); // Prevent transfer to 0x0 address. Use burn() instead
require (balanceOf[_from] >= _value); // Check if the sender has enough
require (balanceOf[_to] + _value >= balanceOf[_to]); // Check for overflows
require(!frozenAccount[_from]); // Check if sender is frozen
require(!frozenAccount[_to]); // Check if recipient is frozen
balanceOf[_from] -= _value; // Subtract from the sender
balanceOf[_to] += _value; // Add the same to the recipient
emit Transfer(_from, _to, _value);
}
function mintToken(address target, uint256 mintedAmount) onlyOwner public {
balanceOf[target] += mintedAmount;
totalSupply += mintedAmount;
emit Transfer(address(0), address(this), mintedAmount);
emit Transfer(address(this), target, mintedAmount);
}
function freezeAccount(address target, bool freeze) onlyOwner public {
frozenAccount[target] = freeze;
}
function setPrices(uint256 newSellPrice, uint256 newBuyPrice) onlyOwner public {
sellPrice = newSellPrice;
buyPrice = newBuyPrice;
}
function buy() payable public {
uint amount = msg.value / buyPrice; // calculates the amount
_transfer(address(this), msg.sender, amount); // makes the transfers
}
function sell(uint256 amount) public {
address myAddress = address(this);
require(myAddress.balance >= amount * sellPrice); // checks if the contract has enough ether to buy
_transfer(msg.sender, address(this), amount); // makes the transfers
msg.sender.transfer(amount * sellPrice); // sends ether to the seller. It’s important to do this last to avoid recursion attacks
}
}

`
批量转账合约:

`
pragma solidity ^0.4.21;
contract Ownable {
address public owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor() public {
owner = msg.sender;
}
modifier onlyOwner() {
require(msg.sender == owner);
_;
}
function transferOwnership(address newOwner) public onlyOwner {
require(newOwner != address(0));
owner = newOwner;
emit OwnershipTransferred(owner, newOwner);
}
}
contract Pausable is Ownable {
event Pause();
event Unpause();
bool public paused = false;
modifier whenNotPaused() {
require(!paused);
_;
}
modifier whenPaused() {
require(paused);
_;
}
function pause() onlyOwner whenNotPaused public {
paused = true;
emit Pause();
}
function unpause() onlyOwner whenPaused public {
paused = false;
emit Unpause();
}
}
contract ERC20Basic {
uint256 public totalSupply;
function balanceOf(address who) public view returns (uint256);
function transfer(address to, uint256 value) public returns (bool);
event Transfer(address indexed from, address indexed to, uint256 value);
}
contract ERC20 is ERC20Basic {
function allowance(address owner, address spender) public view returns (uint256);
function transferFrom(address from, address to, uint256 value) public returns (bool);
function approve(address spender, uint256 value) public returns (bool);
event Approval(address indexed owner, address indexed spender, uint256 value);
}
contract Airdropper is Ownable {
function multisend(address _tokenAddr, address[] dests, uint256[] values) public onlyOwner returns (uint256) {
uint256 i = 0;
while (i < dests.length) {
ERC20(_tokenAddr).transferFrom(msg.sender, dests[i], values[i]);
i += 1;
}
return(i);
}
}

`
合约来源已不记得了。如有侵权请联系作者。

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器
ERC20是以太坊上的代币标准,Java可以通过以太坊的API(如web3j)来与以太坊进行交互,实现授权转账的代码如下: 1. 授权 ```java //导入web3j相关的类 import org.web3j.abi.datatypes.Address; import org.web3j.abi.datatypes.generated.Uint256; import org.web3j.protocol.Web3j; import org.web3j.protocol.core.DefaultBlockParameterName; import org.web3j.protocol.core.methods.response.TransactionReceipt; import org.web3j.tx.Contract; import org.web3j.tx.ManagedTransaction; import org.web3j.tx.TransactionManager; import org.web3j.tx.gas.DefaultGasProvider; //代币合约地址 String contractAddress = "0x12345..."; //代币转账地址 String fromAddress = "0xabcdef..."; //代币接收地址 String toAddress = "0x123456..."; //代币授权数量 BigInteger tokenAmount = BigInteger.valueOf(10000); //创建web3j实例 Web3j web3j = Web3j.build(new HttpService("https://ropsten.infura.io/v3/your-project-id")); //创建交易管理器 TransactionManager transactionManager = new RawTransactionManager(web3j, credentials); //创建代币合约实例 ERC20Token contract = ERC20Token.load(contractAddress, web3j, transactionManager, DefaultGasProvider.GAS_PRICE, DefaultGasProvider.GAS_LIMIT); //授权代币合约 TransactionReceipt approveReceipt = contract.approve(new Address(toAddress), new Uint256(tokenAmount)).send(); ``` 2. 转账 ```java //代币转账数量 BigInteger transferAmount = BigInteger.valueOf(100); //调用代币合约的transferFrom方法实现转账 TransactionReceipt transferReceipt = contract.transferFrom(new Address(fromAddress), new Address(toAddress), new Uint256(transferAmount)).send(); ``` 以上代码中,`ERC20Token`是自定义的Java类,用于与代币合约进行交互,需要根据代币合约的ABI文件生成。具体生成方法可以参考web3j的官方文档。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值