如何使用 solidity 将 ERC20 代币转移到另一个地址?

How to transfer ERC20 tokens to another address using solidity?

我创建了 ERC20 代币,我想将我的代币转移到另一个地址。

我的元掩码中有两个帐户。(帐户 A/B)

我的 ERC20 代码在这里(我在 账户 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()));
    }
}

问题:如何将我的 ERC20 代币从当前地址转移到另一个地址? (A->B)

我在 帐户 A 中使用此代码,但没有用。

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);
    }
}

错误信息

transact to TokenTransfer.stake errored: Internal JSON-RPC error.
{
  "code": 3,
  "message": "execution reverted: ERC20: insufficient allowance",
  "data": "0x08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001d45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000"
}

如何解决?

你的逻辑错了! 如果您想在不通过智能合约的情况下将代币从账户 A 发送到账户 B,您可以使用 Metamask 和其他钱包中可用的 'Send' 选项。 如果你想使用智能合约,你的逻辑就会改变。 在您的智能合约代码中,存在一些错误:

  • _token.approve(address(this), amount):当你写这个声明时,你正在批准智能合约本身来移动你的代币,但它没有任何代币!关于 approve() 函数的另一件事。此操作必须由用户执行,具体来说,一个人必须向智能合约授予访问其钱包的权限;
  • 另一个错误是:智能合约不能没有从账户A调用存款令牌的功能。在这种情况下,当你写这个statament时,_token.transferFrom(msg.sender, to, amount);,(msg.sender是聪明的contract) 你不能将任何金额转移到接收方地址,因为智能合约没有代币数量。
  • 最后一个问题是,当您将代币从智能合约转移到地址时,您必须使用 transfer() 函数而不是 transferFrom(),因为最后一个函数需要批准 + 转移,而智能合约无法自行批准。而 transfer() 仅用于转移资金。

要解决这个问题,你可以看这个智能合约代码:

// 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));
    }
    
}