La estimación de gas falló en Remix

Realmente no puedo usar la función de transferencia tal como está escrita. Se supone que el propietario lo usa. Así que hice una nueva función para la función de "acuñación" para que la use el grifo. No estoy seguro de por qué el mensaje del compilador es tan críptico.

totalSupply_ = totalSupply_.add(_amount);
balances[_to] = balances[_to].add(_amount);
emit Mint(_to, _amount);
emit Transfer(address(0), _to, _amount);

Intentando crear un grifo para mi token ERC-20 y obteniendo un "Error de estimación de gas" cuando ejecuto mi dripTokenfunción que se ve así (ACTUALIZADO):

function dripToken() public {
  require(faucetStatus);
  if(!checkStatus(msg.sender)) revert();
  tokenInstance.updateSupply(oneToken);
  updateStatus(msg.sender, oneMinute);
  tokenInstance.transfer(msg.sender, oneToken);
}

Lo reduje a la línea con la llamada de transferencia que causa el error. Ahora implemento mi token ERC-20 y lo paso al contrato de faucet de la siguiente manera:

constructor(string _fname, address _tokenInstance) public {
  tokenInstance = MyToken(_tokenInstance);
  faucetName = _fname;
  faucetStatus = true;

  emit FaucetOn(faucetStatus);
}

Mi función de transferencia de Token es de https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/token/ERC20/StandardToken.sol Acabo de notar que recibo una advertencia del compilador sobre la función de transferencia que insinúa el problema , pero no entiendo por qué (todavía). Aquí está la advertencia:

Requisito de gas de la función StandardToken.transfer(address,uint256) alto: infinito. Si el requisito de gas de una función es superior al límite de gas del bloque, no se puede ejecutar. Evite bucles en sus funciones o acciones que modifiquen grandes áreas de almacenamiento (esto incluye borrar o copiar arreglos en almacenamiento)

function transfer(address _to, uint256 _value) public returns (bool) {
  require(_value <= balances[msg.sender]);
  require(_to != address(0));

  balances[msg.sender] = balances[msg.sender].sub(_value);
  balances[_to] = balances[_to].add(_value);
  emit Transfer(msg.sender, _to, _value);
  return true;
}

Creo mi Token de la siguiente manera. Ahora lo inicializo con un pequeño suministro.

contract MyToken is StandardToken {
  string public name;                   
  uint8 public decimals;                
  string public symbol;  

  constructor() public {  
    StandardToken.balances[msg.sender] = 1000000000000000000;
    StandardToken.totalSupply_ = 1000000000000000000;                        
    name = "My Token";                             
    decimals = 18; 
    symbol = "MY";      
  }
}

Publiqué mi código en Google Drive: https://drive.google.com/open?id=1EvKEVhD8bR2oKS2W1XNRQpTqVbieUcmC

Es difícil saberlo sin ver la implementación de transfer, pero supongo que falla si el contrato en sí no tiene un saldo lo suficientemente alto. Es posible que solo desee totalSupply_ += oneToken; balanceOf[msg.sender] += oneToken; emit Transfer(0, msg.sender, oneToken);.
Intenté cambiar las líneas como sugeriste. Sigue recibiendo el mismo error. ¿Qué hace emit Transfer? ¿Es esa una función de transferencia diferente? También eliminé mi herencia y ahora paso el contrato simbólico al grifo. Actualicé la publicación original con más código.
Transferes un evento que su token debe emitir cada vez que se transfiere un token. (Por convención, se emite un evento que muestra una transferencia desde la dirección 0 cuando se acuñan nuevos tokens).
Noté que recibo una advertencia con respecto a la función de transferencia, con respecto a la gasolina alta. No estoy seguro de qué lo está causando (todavía). Pegué la advertencia en mi op.
Si comparte suficiente código para reproducir el problema, estaré encantado de probarlo. Es un poco tedioso solo hacer conjeturas.
Gracias por la oferta. Añadido enlace a Google Drive. Noté que estaba ejecutando remix con web3 inyectado. Volví a cambiar a JVM y ya no recibo ningún error de gas, pero la función de transferencia sigue fallando. Se queja de que el constructor no está marcado como pagadero. Pensé que la palabra clave Payable solo se usaba al transferir ETH. Mi error original podría tener que ver con mi configuración de límite de gas. Todavía depurando.
La mención de hacer pagar al constructor es una pista falsa. Creo que está en ese mensaje de error porque es/fue una causa común de reversión de transacciones, pero no está relacionado con su problema.

Respuestas (2)

Vea la parte superior de OP para la respuesta. Creo que fue el bloque require el que falló. No estoy seguro de por qué el compilador es tan críptico al respecto.

Debe especificar la dirección que está llamando transferencia. Por ejemplo, si está intentando transferir un token ERC20, el código sería el siguiente:

ERC20TokenAddress.transfer(msg.sender, oneToken);

Sin la dirección inicial, la EVM no sabe qué se está transfiriendo.

¿Cómo obtengo la dirección? Actualmente estoy definiendo el contrato de faucet de la siguiente manera: contract Faucet es ERC20Token. ¿Sería mejor implementar el contrato ERC20Token y luego pasar la dirección al contrato Faucet a través del constructor y simplemente eliminar la herencia?
Si tu puedes hacerlo. La otra opción es tener una setAddress()función. pareceríafunction setAddress(address tokenAddress) onlyOwner { ERC20TokenAddress = tokenAddress; }
No hay nada de malo en que el mismo contrato sea el token ERC20 y tenga la dripToken()función.
Noté que recibo una advertencia con respecto a la función de transferencia, con respecto a la gasolina alta. No estoy seguro de qué lo está causando (todavía). Pegué la advertencia en mi op.