조규선
조규선

Reputation: 93

How to transfer ERC20 tokens to another address using solidity?

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

Answers (1)

Antonio Carito
Antonio Carito

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;
  • Another error is: smart contract cannot failt to have a function about deposit token to call from account A. In this case, when you write this statament, _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.
  • Last problem, is when you transfer a token from smart contract to address you must use 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

Related Questions