通过合同发送令牌时出现SafeMath错误

时间:2019-09-01 17:10:43

标签: token ethereum solidity

在尝试通过合同发送令牌时,我遇到错误消息:“ SafeMath:减法溢出”。

最初,我仅使用传输功能。但是,正如我认为的那样,msg.sender只需将其令牌发送给其他用户(通过松露控制台,这没有问题)。但是,阅读[this]后,我得到的印象是,实际上是合同地址成为了TokenContract中的msg.sender。因此,我认为(仅作为帐户,而不是合同本身)我必须先向令牌发送令牌,然后再批准允许该合同代表msg.sender发送令牌并随后转移资金。但是,我仍然遇到SafeMath错误。

TokenContract(不是下面的接口)实现了我的代码的最简单版本如下:

contract ContractA {

    function pay () public returns (bool) {

        TokenContract tk = TokenContract("tokenContractAddress");
        tk.transferFrom(msg.sender, address(this), 5);
        tk.approve(address(this), 5);
        tk.transfer("someAccount", 5);

        return true;
    }
}

interface TokenContract {
    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
    function approve(address spender, uint256 amount) external returns (bool);
    function transfer(address recipient, uint256 amount) external returns (bool);   
}

contract TokenContract is ERC20, ERC20Detailed {
    constructor() ERC20Detailed("Token", "TKN", 18) public {
        _mint(msg.sender, 1000);
    }
}

很明显,我希望不会出现safeMath错误。当我转帐并批准时。我只是期望与使用松露控制台时的行为相同。

1 个答案:

答案 0 :(得分:3)

我假设调用ContractA的地址没有为合同设置津贴。

  

要求:
  *呼叫者必须允许至少sender的{​​{1}}令牌使用。   https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v2.3.0/contracts/token/ERC20/ERC20.sol

amount
  1. 合同发起人 /** * @dev See `IERC20.transferFrom`. * * Emits an `Approval` event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of `ERC20`; * * Requirements: * - `sender` and `recipient` cannot be the zero address. * - `sender` must have a balance of at least `value`. * - the caller must have allowance for `sender`'s tokens of at least * `amount`. */ function transferFrom(address sender, address recipient, uint256 amount) public returns (bool) { _transfer(sender, recipient, amount); _approve(sender, msg.sender, _allowances[sender][msg.sender].sub(amount)); return true; } 对该代币进行配额
  2. 合同呼叫者A调用approve函数,并调用pay在先前设置的限额内从用户转移到接收者。

如果您正在创建ERC20令牌,则可能需要查看OpenZeppelin Contracts实施以查看它是否满足您的需求。有关详细信息,请参见文档:https://docs.openzeppelin.com/contracts/2.x/tokens#ERC20

如果您要转移各种ERC20令牌,则可能要考虑使用SafeERC20包装器进行以下调用:https://docs.openzeppelin.com/contracts/2.x/api/token/erc20#SafeERC20

如果您需要ERC20的界面,则可能需要使用IERC20:https://docs.openzeppelin.com/contracts/2.x/api/token/erc20#IERC20

或者,对于ERC20,您可以考虑创建ERC777令牌(无需在两个单独的事务中进行批准和transferFrom)。有关详细信息,请参见文档:https://docs.openzeppelin.com/contracts/2.x/tokens#ERC777

如果您对使用OpenZeppelin有疑问,可以在社区论坛中提问:https://forum.openzeppelin.com/

披露:我是OpenZeppelin的社区经理