Remix: el gas requerido excede la asignación o siempre falla la transacción

Entorno: Remix web IDE, red de prueba Ropsten.

A continuación se muestra mi contrato:

pragma solidity ^0.4.16;

contract TokenERC20 {
    // Public variables of the token
    string public name;
    string public symbol;
    uint8 public decimals = 18;
    uint256 public totalSupply;

    // This creates an array with all balances
    mapping (address => uint256) public balanceOf;

    // This generates a public event on the blockchain that will notify clients
    event Transfer(address indexed from, address indexed to, uint256 value);

    function TokenERC20(
        uint256 initialSupply,
        string tokenName,
        string tokenSymbol
    ) public {
        totalSupply = initialSupply * 10 ** uint256(decimals);  // Update total supply with the decimal amount
        balanceOf[msg.sender] = totalSupply;                // Give the creator all initial tokens
        name = tokenName;                                   // Set the name for display purposes
        symbol = tokenSymbol;                               // Set the symbol for display purposes
    }

    /**
     * Internal transfer, only can be called by this contract
     */
    function _transfer(address _from, address _to, uint _value) internal {
        // Prevent transfer to 0x0 address. Use burn() instead
        require(_to != 0x0);
        // Check if the sender has enough
        require(balanceOf[_from] >= _value);
        // Check for overflows
        require(balanceOf[_to] + _value >= balanceOf[_to]);
        // Save this for an assertion in the future
        uint previousBalances = balanceOf[_from] + balanceOf[_to];
        // Subtract from the sender
        balanceOf[_from] -= _value;
        // Add the same to the recipient
        balanceOf[_to] += _value;
        emit Transfer(_from, _to, _value);
        // Asserts are used to use static analysis to find bugs in your code. They should never fail
        assert(balanceOf[_from] + balanceOf[_to] == previousBalances);
    }


    function transfer(address _to, uint256 _value) public returns (bool success) {
        _transfer(msg.sender, _to, _value);
        return true;
    }

}

Es muy básico, puedo implementar este contrato con éxito. Pero cuando llamo a esta función de transferencia, recibí la advertencia:

Gas estimation errored with the following message (see below). The transaction execution will likely fail. Do you want to force sending? 
Error: gas required exceeds allowance or always failing transaction at chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/background.js:1:1401895 at chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/background.js:1:931969 at chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/background.js:1:350331 at o (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/background.js:1:368562) at chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/background.js:1:353161 at chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/background.js:1:350331 at c (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/background.js:1:353437) at chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/background.js:1:353475 at Ht (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/background.js:1:362844) at Object.<anonymous> (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/background.js:1:353564) at e.value (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/background.js:1:932884) at chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/background.js:1:932451 at n (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/background.js:1:368506) at o (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/background.js:1:368584) at chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/background.js:1:353161 at chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/background.js:1:932417 at n (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/background.js:1:368506) at o (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/background.js:1:368584) at chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/background.js:1:353161 at chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/background.js:1:932790 at chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/background.js:1:353971 at chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/background.js:1:350331 at c (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/background.js:1:353437) at s (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/background.js:1:353359) at chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/background.js:1:353161 at chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/background.js:1:353951 at chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/background.js:1:932672 at chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/background.js:1:931109 at i (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/background.js:1:1070338)

Si trato de ejecutar esta función a la fuerza, la transacción fallará. Alguien sabe qué le pasa a mi código, ¡gracias chicos!

Respuestas (1)

Probé su contrato en remix y funcionó como se esperaba.

Si transfer()falla, la causa más probable es que parte de la condición del require()es falsa. Por ejemplo, la cuenta desde la que envía tokens no tiene suficientes tokens.

Al inicio solo la cuenta que despliega el contrato tendrá saldo distinto de cero.