智能合约无法在合约内部添加转账功能

Smart Contract can not add transfer function inside the contract

如何使用 openZeppelin 在合约上为用户添加转账功能?

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.2;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract TokenSample is ERC20 {
    constructor() ERC20("TokenSample", "SMPL") {
        _mint(msg.sender, 21000000 * 10 ** decimals());
    }
}

当我部署上述合约时,我得到了一个带有 2 个参数(收件人、金额)的转账表格。没关系。

但是因为一个原因,我需要在合约里面实现自己的转账函数

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.2;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract TokenSample is ERC20 {
    constructor() ERC20("TokenSample", "SMPL") {
        _mint(msg.sender, 21000000 * 10 ** decimals());
    }

 function getToken(uint256 _amount) external returns(bool)  {
   // my internal logic here
   transfer(msg.sender, _amount);
    return true;
 }
}

从代码中我得到错误:ERC20:转账金额超过余额

我不太确定,但我猜这是因为令牌属于所有者而不属于合同。实施该 getToken 方法的正确方法是什么?

transfer amount exceeds balance 错误消息来自于发件人是否有足够余额的检查失败。资料来源:OpenZeppelin 上的 ERC20.sol GitHub。

如果 transfer() 函数是从合约函数中调用的(而不是直接由用户调用),发送方就是合约。

所以你合同中的这一行

transfer(msg.sender, _amount);

正在尝试从合约地址 发送 _amount 个代币 给用户(执行 getToken() 函数)。当它试图传输比发送方(合约)拥有的更多的代币时,它会失败并显示此错误消息。


通过这种方式,您可以为用户铸造新代币(增加总供应量)。

function getToken(uint256 _amount) external {
    // TODO your own logic here
    _mint(msg.sender, _amount);
}

如果你想在部署过程中将一些代币铸造到合约地址,你可以使用address(this)作为接收者,它代表当前合约地址。

constructor() {
    // mint 10M tokens to the contract
    _mint(address(this), 10000000 * 10 ** decimals());
    
    // mint 21M tokens to the owner
    _mint(msg.sender, 21000000 * 10 ** decimals());

    // total supply is now 31M, where the contract owns 10M and the owner owns 21M
}