¿Por qué mi contrato de Crowdsale no me deja comprar?

Buen día, he diseñado un token mintable que tiene un suministro máximo, ahora quiero vender ese token en un Crowdsale. Creé el contrato de venta colectiva, configuré la dirección del token, transfirí los fondos... pero luego, cuando invoco la opción de compra, arroja un error. 1. ¿Podría alguien ayudarme con este problema y 2. ¿Cómo puedo permitir que solo ciertas personas compren del Contrato? Gracias de antemano.

LA FUNCIÓN DE COMPRA ESTÁ EN CONTRATO DE CROWDSALE (SEGUNDA ÚLTIMA FUNCIÓN)

Código de identificador:

pragma solidity >=0.4.22 <0.8.0;
 
contract ContexT {
    constructor () internal { }
    // solhint-disable-previous-line no-empty-blocks
 
    function _msgSender() internal view returns (address payable) {
        return msg.sender;
    }
 
    function _msgData() internal view returns (bytes memory) {
        this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
        return msg.data;
    }
}
 
interface IERc20 {
    function totalSupply() external view returns (uint);
    function balanceOf(address account) external view returns (uint);
    function transfer(address recipient, uint amount) external returns (bool);
    function allowance(address owner, address spender) external view returns (uint);
    function approve(address spender, uint amount) external returns (bool);
    function transferFrom(address sender, address recipient, uint amount) external returns (bool);
    event Transfer(address indexed from, address indexed to, uint value);
    event Approval(address indexed owner, address indexed spender, uint value);
}
 
library SafeMatH {
    function add(uint a, uint b) internal pure returns (uint) {
        uint c = a + b;
        require(c >= a, "SafeMatH: addition overflow");
 
        return c;
    }
    function sub(uint a, uint b) internal pure returns (uint) {
        return sub(a, b, "SafeMatH: subtraction overflow");
    }
    function sub(uint a, uint b, string memory errorMessage) internal pure returns (uint) {
        require(b <= a, errorMessage);
        uint c = a - b;
 
        return c;
    }
    function mul(uint a, uint b) internal pure returns (uint) {
        if (a == 0) {
            return 0;
        }
 
        uint c = a * b;
        require(c / a == b, "SafeMatH: multiplication overflow");
 
        return c;
    }
    function div(uint a, uint b) internal pure returns (uint) {
        return div(a, b, "SafeMatH: division by zero");
    }
    function div(uint a, uint b, string memory errorMessage) internal pure returns (uint) {
        // Solidity only automatically asserts when dividing by 0
        require(b > 0, errorMessage);
        uint c = a / b;
 
        return c;
    }
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        return mod(a, b, "SafeMatH: modulo by zero");
    }
 
    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts with custom message when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b != 0, errorMessage);
        return a % b;
    }
}
 
//**
library AddresS {
    function isContract(address account) internal view returns (bool) {
        bytes32 codehash;
        bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
        // solhint-disable-next-line no-inline-assembly
        assembly { codehash := extcodehash(account) }
        return (codehash != 0x0 && codehash != accountHash);
    }
}
//*/
 
contract ERC20 is ContexT, IERc20 {
    using SafeMatH for uint;
 
    mapping (address => uint) private _balances;
 
    mapping (address => mapping (address => uint)) private _allowances;
 
    uint private _totalSupply;
 
    function totalSupply() public view returns (uint) {
        return _totalSupply;
    }
    function balanceOf(address account) public view returns (uint) {
        return _balances[account];
    }
    function transfer(address recipient, uint amount) public returns (bool) {
        _transfer(_msgSender(), recipient, amount);
        return true;
    }
    function allowance(address owner, address spender) public view returns (uint) {
        return _allowances[owner][spender];
    }
    function approve(address spender, uint amount) public returns (bool) {
        _approve(_msgSender(), spender, amount);
        return true;
    }
    function transferFrom(address sender, address recipient, uint amount) public returns (bool) {
        _transfer(sender, recipient, amount);
        _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance"));
        return true;
    }
    function increaseAllowance(address spender, uint addedValue) public returns (bool) {
        _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));
        return true;
    }
    function decreaseAllowance(address spender, uint subtractedValue) public returns (bool) {
        _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero"));
        return true;
    }
    function _transfer(address sender, address recipient, uint amount) internal {
        require(sender != address(0), "ERC20: transfer from the zero address");
        require(recipient != address(0), "ERC20: transfer to the zero address");
 
        _beforeTokenTransfer(sender, recipient, amount); // Added bi Jude
 
        _balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance");
        _balances[recipient] = _balances[recipient].add(amount);
        emit Transfer(sender, recipient, amount);
    }
    function _mint(address account, uint amount) internal {
        require(account != address(0), "ERC20: mint to the zero address");
 
        _beforeTokenTransfer(address(0), account, amount); // Added bi Jude
 
        _totalSupply = _totalSupply.add(amount);
        _balances[account] = _balances[account].add(amount);
        emit Transfer(address(0), account, amount);
    }
    function _burn(address account, uint amount) internal {
        require(account != address(0), "ERC20: burn from the zero address");
 
        _beforeTokenTransfer(account, address(0), amount); // Added bi Jude
 
        _balances[account] = _balances[account].sub(amount, "ERC20: burn amount exceeds balance");
        _totalSupply = _totalSupply.sub(amount);
        emit Transfer(account, address(0), amount);
    }
    function _approve(address owner, address spender, uint amount) internal {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");
 
        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }
    function _beforeTokenTransfer(address from, address to, uint256 amount) internal { } // Added bi Jude
}
 
 
contract ERC20Detailed is IERc20 {
    string private _name;
    string private _symbol;
    uint8 private _decimals;
    uint256 private  TokenmaxSupply = 700000*10**18;
 
    constructor (string memory name, string memory symbol, uint8 decimals) public {
        _name = name;
        _symbol = symbol;
        _decimals = decimals;
    }
    function name() public view returns (string memory) {
        return _name;
    }
    function symbol() public view returns (string memory) {
        return _symbol;
    }
    function decimals() public view returns (uint8) {
        return _decimals;
    }
    
     function maxSupply() public view returns (uint256) {
        return TokenmaxSupply;
    }
}
 
 
library SafeERc20 {
    using SafeMatH for uint;
    using AddresS for address;
 
    function safeTransfer(IERc20 token, address to, uint value) internal {
        callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
    }
 
    function safeTransferFrom(IERc20 token, address from, address to, uint value) internal {
        callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
    }
 
    function safeApprove(IERc20 token, address spender, uint value) internal {
        require((value == 0) || (token.allowance(address(this), spender) == 0),
            "SafeERc20: approve from non-zero to non-zero allowance"
        );
        callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
    }
    function safeIncreaseAllowance(IERc20 token, address spender, uint256 value) internal {
        uint256 newAllowance = token.allowance(address(this), spender).add(value);
        callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    } // Added bi Jude
 
    function safeDecreaseAllowance(IERc20 token, address spender, uint256 value) internal {
        uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERc20: decreased allowance below zero");
        callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    } // Added bi Jude
    function callOptionalReturn(IERc20 token, bytes memory data) private {
        require(address(token).isContract(), "SafeERc20: call to non-contract");
 
        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = address(token).call(data);
        require(success, "SafeERc20: low-level call failed");
 
        if (returndata.length > 0) { // Return data is optional
            // solhint-disable-next-line max-line-length
            require(abi.decode(returndata, (bool)), "SafeERc20: ERC20 operation did not succeed");
        }
    }
}
 
contract MyToken is ERC20, ERC20Detailed {
  using SafeERc20 for IERc20;
  using AddresS for address;
  using SafeMatH for uint;
  
  
  address public governance;
  mapping (address => bool) public minters;
 
  constructor () public ERC20Detailed("Double01 Token", "D01", 18) {
      governance = tx.origin;
      addMinter(msg.sender);
      mint(msg.sender, 250000000000000000000000);
      //_mint(msg.sender, 25000000000000000000000); // Mint 250k tokens
  }
 
  function mint(address account, uint256 amount) public {
      
      require(totalSupply() + amount <= maxSupply(), "Supply Max Reached");
      require(minters[msg.sender], "!minter");
      _mint(account, amount);
  }
  
 
  function setGovernance(address _governance) public {
      require(msg.sender == governance, "!governance");
      governance = _governance;
  }
  
  function addMinter(address _minter) public {
      require(msg.sender == governance, "!governance");
      minters[_minter] = true;
  }
  
  function removeMinter(address _minter) public {
      require(msg.sender == governance, "!governance");
      minters[_minter] = false;
  }
} 

Compre parte del contrato de Crowdsale:


pragma solidity ^0.7.3;

    function buy() public payable {
        require((block.timestamp > startTime ) && (block.timestamp < endTime)  , " Token Crowdsate is not active");
        uint256 weiValue = msg.value;
        require((weiValue >= minimumBuyAmount) && (weiValue <= maximumBuyAmount), "Minimum amount is 0.1 eth / Maximum amount is 1 eth ");
        uint256 amount = weiValue.mul(priceFactor);
        Token token = Token(tokenAddress);
        require(walletAddress.send(weiValue));
        require(token.tokensSold(msg.sender, amount));
        totalSold += amount;
        emit TokensSold(msg.sender, amount);
    }
}

He implementado en diferentes compiladores

it throws an error- ¿Qué error?
nada específico, solo transacción revertida
when I call the buy option- ¿Dónde está el código que hace eso?
En contrato crowdsale, penúltima función
¡Esa es la función en sí, no cómo la llamas! Debe proporcionar TODOS los detalles relevantes y SOLO los detalles relevantes. Has hecho... tampoco. Aquí hay una tonelada de código irrelevante, que los lectores de su pregunta deben revisar. Luego, faltan algunas piezas que realmente se requieren para responderla. Por favor, arregla.
Ok, pero vas a criticar mi pregunta o me vas a ayudar jajaja?
Te ayudaré cuando tenga suficientes datos para ayudarte. Como habrás notado, he estado tratando de ayudarte pidiéndole la información que falta. Pero tal como está, la calidad de su pregunta es bastante baja.
ok, te lo agradezco. Si necesita alguna pregunta, no dude en preguntar
¡Lo acabo de hacer, no respondiste! - when I call the buy option- ¿Cómo lo llamas?
Ver aquí: PASO 1: ibb.co/g4HkpfM PASO 2: ibb.co/FxpYF6g
Publíquelo como texto sin formato (sin enlaces ni imágenes) y como parte de la pregunta (no en los comentarios). Mientras lo hace, deshágase de todo el código que sea irrelevante para el problema que está experimentando. Nadie aquí (incluyéndome a mí) debería estar investigando esta tonelada de detalles irrelevantes para resolver el problema.
Entonces, la función de compra me da la opción de escribir un valor de éter. Luego escribo cualquier valor entre 0,1 o 1. Luego escribo en el contrato haciendo clic en escribir. Luego, Metamask arroja un error que dice: "excepción lanzada en el código del contrato"
Hay una variable en la buy()función que no está definida en ninguna parte con el nombre de walletAddress. ¿Podría ese ser el problema?

Respuestas (1)

Reemplazaría el walletAddress.sendto msg.sender.senden su buy()función y le daría otra oportunidad.

No funciona. walletAddress se define como sigue en el contrato de crowdsale (Nota, ese no es el contrato de crowdsale completo): ,,, address payable public walletAddress; ,,, Y luego se establece en la billetera que implementó el contrato