繁体   English   中英

收到错误“ERC 20 津贴不足”我的合同

[英]Get an error "ERC 20 insufficent allowance" my contract

我被卡住了,我不明白错误在哪里......

是一个彩票项目,问题出现在 lottery.sol 合同中的ABid function。

下面我附上了我的代码:

LotteryToken.sol

//SPDX-License-Identifier: MIT

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


pragma solidity ^0.8.4;

contract LotteryToken is Ownable, ERC20{

    mapping(address=>uint)private _balances;


    constructor(string memory name, string memory symbol, uint totalSupply)ERC20(name, symbol){
        _mint(msg.sender, totalSupply);
        _balances[msg.sender] = totalSupply;

    }

    

    function increaseAllowance(address spender, uint256 addedValue) public virtual override returns (bool) {
        address owner = owner();
        _approve(owner, spender, allowance(owner, spender) + addedValue);
        return true;
    }



    function _transfer(
        address _from,
        address _to,
        uint _amount
        )internal virtual override{
            _balances[_from] -= _amount;
            _balances[_to] += _amount;
            super._transfer(_from, _to, _amount);
        }
    


    function balanceOf(address account)public view virtual override returns(uint){
        return _balances[account];
    }

}

彩票.sol

//SPDX-License-Identifier: MIT

import "@openzeppelin/contracts/access/Ownable.sol";
import "./LotteryToken.sol";
import "./LotteryInfo.sol";

pragma solidity ^0.8.4;

contract Lottery is Ownable{

    LotteryInfo private lotteryInfo;
    LotteryToken private lotteryToken;

    event BidCorrect(address bidder, uint tokenId, uint defaultBid);

    constructor(){

    }


    function initLotteryTokenContract(address _lotteryTokenContract)public onlyOwner{
        lotteryToken = LotteryToken(_lotteryTokenContract);
        lotteryToken.increaseAllowance(address(this), lotteryToken.balanceOf(lotteryToken.owner()));
    }



    function initLotteryInfoContract(address _lotteryInfoContract)public onlyOwner{
        lotteryInfo = LotteryInfo(_lotteryInfoContract);
    }

    

    function setItemToWin(
        string memory _name,
        uint _defaultBid,
        uint _endingTimeLottery
        )public onlyOwner{
            require(_endingTimeLottery > block.timestamp, "Cannot set a date in the Past!");
            lotteryInfo.setItemToWin(_name, _defaultBid, _endingTimeLottery);
    }



    function buyTokens(uint _quantity)external payable{
        uint singleTokenPrice = 0.02 ether;
        uint finalPrice = singleTokenPrice * _quantity;
        require(msg.sender != owner() && msg.sender != lotteryToken.owner(), "Admin Cannot Buy Tokens!");
        require(msg.value == finalPrice, "Please set the right price!");
        payable(owner()).transfer(msg.value);
        address lotterytokenOwner = lotteryToken.owner();
        lotteryToken.transferFrom(lotterytokenOwner, msg.sender, _quantity);
    }



    function placeABid(uint _tokenIds)external{
        require(block.timestamp < lotteryInfo.getEndingTimeLottery(_tokenIds), "Lottery is closed!");
        require(msg.sender != owner() && msg.sender != lotteryToken.owner(), "Admin Cannot Place A Bid!");
        uint requiredTokenAmounts = lotteryInfo.getDefaultItemBid(_tokenIds);
        require(lotteryToken.balanceOf(msg.sender) >= requiredTokenAmounts, "No Necessary Funds To Partecipate!");
        address lotteryTokenOwner = lotteryToken.owner();
        lotteryToken.transferFrom(msg.sender, lotteryTokenOwner, requiredTokenAmounts);
        lotteryInfo.updateBid(_tokenIds, requiredTokenAmounts);
        lotteryInfo.updateAddress(_tokenIds, msg.sender);
        emit BidCorrect(msg.sender, _tokenIds, requiredTokenAmounts);
    }

还有另一个合同 LotteryInfo 但不需要了解问题。

我想要做的是出价并将出价金额发送回 lotteryToken.owner() 但我收到错误还原“ERC20 配额不足”。 有人可以解释我为什么吗? 非常感谢

您必须从“placeABid”function 的调用方调用“批准”方法。 他/她必须批准您的彩票合约才能使用(调用 transferFrom)他/她的 ERC20 代币。 如果不增加 ERC20 的许可(批准),您将无法从 msg.sender 提取 ERC20 代币。

您也可以从 OpenZeppelin 库中详细检查 ERC20 标准合约。

首先,您必须从“placeABid”function 的调用者调用“批准”方法。 然后人们必须批准您的彩票合约才能使用(调用 transferFrom)ERC20 代币。 如果不增加 ERC20 的许可(批准),您将无法从 msg.sender 提取 ERC20 代币。

如果amount是最大值uint256 ,则不会在 * transferFrom上更新配额。 这在语义上等同于无限批准。 * 要求: - spender者不能是零地址。

这是一个参考链接

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM