Reputation: 93
I create ERC20 tokens, and i want to transfer my tokens to another address.
I have two accounts in my metamask.(Account A/B)
My ERC20 code's here (I deployed and save tokens in account A)
pragma solidity ^0.8.0;
// SPDX-License-Identifier: MIT
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol";
contract MyToken is ERC20 {
constructor(string memory name, string memory symbol) ERC20(name,symbol) {
// mint 1000 token
_mint(msg.sender, 1000*10**uint(decimals()));
}
}
Question : how can I transfer my ERC20 tokens from the current address to another? (A->B)
I use this code in account A, but not work.
pragma solidity ^0.8.7;
// SPDX-License-Identifier: MIT
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol";
contract TokenTransfer {
IERC20 _token;
// token = MyToken's contract address
constructor(address token) public {
_token = IERC20(token);
}
// to = Account B's address
function stake(address to, uint amount) public {
_token.approve(address(this), amount);
require(_token.allowance(address(this), address(this)) >= amount);
_token.transferFrom(msg.sender, to, amount);
}
}
error message
transact to TokenTransfer.stake errored: Internal JSON-RPC error.
{
"code": 3,
"message": "execution reverted: ERC20: insufficient allowance",
"data": "0x08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001d45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000"
}
how to fix it?
Upvotes: 4
Views: 13103
Reputation: 1387
Your logic is wrong! If you want to send a token from account A to account B without passing from smart contract, you can use 'Send' options available in Metamask and other wallet. If you want use a smart contract, your logic change. In your smart contract code, there are some errors:
_token.approve(address(this), amount)
: when you write this statement, you're approving smart contract itself to move your tokens but it doesn't have any token! Another thing about approve()
function. This operation must be do from user, in details a person must to give to smart contract permission accessing about his wallet;_token.transferFrom(msg.sender, to, amount);
, (msg.sender
is smart contract) you cannot transfer any amount to receiver address because smart contract doesn't have the amount of tokens.transfer()
function instead transferFrom()
because this last function require approve + transfer and smart contracts cannot approve itself. While transfer()
is used only transfer funds.To resolve this problems, you can see this smart contract code:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol";
contract TokenTransfer {
IERC20 _token;
// token = MyToken's contract address
constructor(address token) {
_token = IERC20(token);
}
// Modifier to check token allowance
modifier checkAllowance(uint amount) {
require(_token.allowance(msg.sender, address(this)) >= amount, "Error");
_;
}
// In your case, Account A must to call this function and then deposit an amount of tokens
function depositTokens(uint _amount) public checkAllowance(_amount) {
_token.transferFrom(msg.sender, address(this), _amount);
}
// to = Account B's address
function stake(address to, uint amount) public {
_token.transfer(to, amount);
}
// Allow you to show how many tokens owns this smart contract
function getSmartContractBalance() external view returns(uint) {
return _token.balanceOf(address(this));
}
}
Upvotes: 15