Error de estimación de gas con el siguiente mensaje

Recibí el mensaje "Error en la estimación de gas con el siguiente mensaje (ver a continuación). Es probable que la ejecución de la transacción falle. ¿Desea forzar el envío? Error interno de JSON-RPC". en remix usando la función drawWinner

    pragma solidity ^0.4.18;

    contract RecurringLottery {
         struct Round {
            uint deployBlock;
            uint endBlock;
            uint drawBlock;
            Entry[] entries;
            uint totalQuantity;
            address winner;
       }
struct Entry {
    address buyer;
    uint quantity;
}

uint constant public TICKET_PRICE = 1e15;

mapping(uint => Round) public rounds;
uint public round;
uint public duration;
mapping (address => uint) public balances;

// duration is in blocks. 1 day = ~5500 blocks
function RecurringLottery (uint _duration) public {
    round = 1;
    duration = _duration;
    rounds[round].deployBlock = block.number;
    rounds[round].endBlock = block.number + duration;
    rounds[round].drawBlock = block.number + duration + 5;
}

function buy () payable public {
    require(msg.value % TICKET_PRICE == 0);

    if (block.number > rounds[round].endBlock) {
        round += 1;
        rounds[round].deployBlock = block.number;
        rounds[round].endBlock = block.number + duration;
        rounds[round].drawBlock = block.number + duration + 5;
    }

    uint quantity = msg.value / TICKET_PRICE;
    Entry memory entry = Entry(msg.sender, quantity);
    rounds[round].entries.push(entry);
    rounds[round].totalQuantity += quantity;
}

function drawWinner (uint roundNumber) public {
    Round storage drawing = rounds[roundNumber];
    require(drawing.winner ==  address(0));
    require(block.number > drawing.drawBlock);
    require(drawing.entries.length > 0);

    // pick winner
    bytes32 rand = keccak256(
        block.blockhash(drawing.drawBlock)
    );
    uint counter = uint(rand) % drawing.totalQuantity;
    for (uint i=0; i < drawing.entries.length; i++) {
        uint quantity = drawing.entries[i].quantity;
        if (quantity > counter) {
            drawing.winner = drawing.entries[i].buyer;
            break;
        }
        else
            counter -= quantity;
    }

    balances[drawing.winner] += TICKET_PRICE * drawing.totalQuantity;
}

function withdraw () public {
    uint amount = balances[msg.sender];
    balances[msg.sender] = 0;
    msg.sender.transfer(amount);
}

function deleteRound (uint _round) public {
    require(block.number > rounds[_round].drawBlock + 100);
    require(rounds[_round].winner != address(0));
    delete rounds[_round];
}

function () payable public {
    buy();
}

}

Respuestas (5)

Por lo general, obtiene ese error cuando falla la ejecución del código, esto puede deberse a una ejecución regular o porque una de las reversiones está detectando un error, en su caso, el problema fueron las reversiones, así es como puede averiguarlo:

Esta característica aún no está en los nodos, solo en javascriptVM que puede usar en remix, o en sus pruebas de trufa/ganache, pero se recomienda que comience a usarla ahora; puede agregar un mensaje de error a sus reversiones, esta es la forma más fácil de obtener mejores errores integrales, IE:

require(condition, "string returned if condition fails");

Tenga en cuenta que estoy usando javascript vm para este ejemplo en lugar de inyectar web3. Cuando ejecuto tu código, el primer error que podemos encontrar está en el segundo require:

require(block.number > drawing.drawBlock, "Can't draw yet");

No podemos dibujar hasta que hayan pasado algunos bloques, forcé la generación de algunos bloques en la VM llamando a otras funciones, si está haciendo esto en ethereum, solo necesita esperar.

Después de resolver este problema, se bloqueó en la siguiente línea:

require(drawing.entries.length > 0, "No entries for that round");

Así que llamé a buy() un par de veces y envié la cantidad de éter especificada en TICKET_PRICE, luego verifiqué que las entradas se agregaron llamando a rounds(numberOfRound), y después de llamar a drawWinner(numberOfRound) con una ronda válida, la función funcionó correctamente. .

Debes crear una llamada que te diga si esa función funcionará o fallará revisando esas condiciones, de esa manera puedes resolver un montón de dolores de cabeza, recuerda poner mensajes de error en require, y si quieres ver todo paso a paso. paso, el depurador provisto en remix es bastante útil.

TLDR: para que su código funcione, debe asegurarse de que hayan pasado suficientes bloques y que la ronda tenga al menos una entrada.

Por cierto, hay un par de vulnerabilidades en su función drawWinner(), ¡no la use en producción!

Al usar el IDE de REMIX, tenía que asegurarme de establecer el valor en TICKET_PRICE. Ver imagen, dónde configurarlo.

ingrese la descripción de la imagen aquí

Ejecuté tu código en remix, todo está bien. Tal vez olvidó seleccionar la versión de compilador adecuada.

    0.4.25+commit.59dbf8f1

¡Esto era mío! Espero eso ayude.

Gracias, sin embargo, sigo recibiendo este error "Transacción extraída pero la ejecución falló" con la función dibujarGanador
Esto sucede cuando una de sus condiciones assert()o revert()devuelve falso. Por lo tanto, la transacción se extrajo pero la ejecución falló.
Cómo puedo arreglarlo ?
Intente cambiar esta línea: require(drawing.winner == address(0));a esta línea: require(drawing.winner != address(0));en la drawWinner()función.
sigue el mismo error :((
Tendrá que esperar hasta que se le mencione el tamaño del bloque + 5 como ha mencionado:rounds[round].drawBlock = block.number + duration + 5;

En mi caso, tuve que cambiar de la versión 0.8.7 de solc a la 0.8.0 y funciona.

Está recibiendo un error de estimación de gas fallido, esto significa:

  1. No tienes suficiente ETH para realizar esta transacción
  • Si este es el caso, obtenga más ETH
  1. No tiene suficiente token ERC20 para realizar esta transacción (como LINK, DAI, etc.)
  • Si este es el caso, obtenga más del token ERC20 o financie su contrato con LINK.
  1. Tienes algún otro problema con la ruptura de tu lógica.
  • Si este es el caso, actualice la pregunta con comentarios.