¿Qué sucede cuando realiza una llamada de programación recursiva con el programador Ethereum Alarm Clock?

Mi objetivo es programar una llamada una vez al día.

[P] ¿Es posible usar la función recursiva para programar una llamada una vez al día usando el programador Ethereum Alarm Clock?

Ejemplo de la siguiente respuesta https://ethereum.stackexchange.com/a/87/4575 :

contract SchedulerAPI { 
    function scheduleCall(address contractAddress,
                          bytes4 abiSignature,
                          uint targetBlock) public returns (address); }

contract CallMeLater {
    // The address of the v0.6.0 Alarm Clock scheduler contract.
    address constant Scheduler = SchedulerAPI(0xe109ecb193841af9da3110c80fdd365d1c23be2a);

    function CallMeLater() {
        // Schedule a call to the `callback` function
        Scheduler.value(2 ether).scheduleCall(
            address(this),               // the address that should be called.
            bytes4(sha3("callback()")),  // 4-byte abi signature of callback fn
            block.number + 5082,          // the block number to execute the call 
        );               //As we know 1 day duration (1440 minutes): 5082 blocks.
    }

    function callback() public {
        // whatever code you want executed.
          CallMeLater(); //added: recursive call.
    } }

Agregué más CallMeLater();al final de callback()la función, supongo, lo que hará un nuevo horario (1 día antes) para llamar callback().

Respuestas (2)

Solución

El protocolo cambió desde que se publicó la pregunta. Es posible realizar llamadas recursivas mediante la creación de un servicio que, por ejemplo, aproveche la billetera Proxy (para financiar las siguientes llamadas).

Ethereum Alarm Clock tiene un ejemplo de RecurringPayment en su repositorio. Este es el contrato:

pragma solidity 0.4.24;

import "contracts/Interface/SchedulerInterface.sol";

/// Example of using the Scheduler from a smart contract to delay a payment.
contract RecurringPayment {
    SchedulerInterface public scheduler;

    uint paymentInterval;
    uint paymentValue;
    uint lockedUntil;

    address recipient;
    address public currentScheduledTransaction;

    event PaymentScheduled(address indexed scheduledTransaction, address recipient, uint value);
    event PaymentExecuted(address indexed scheduledTransaction, address recipient, uint value);

    function RecurringPayment(
        address _scheduler,
        uint _paymentInterval,
        uint _paymentValue,
        address _recipient
    )  public payable {
        scheduler = SchedulerInterface(_scheduler);
        paymentInterval = _paymentInterval;
        recipient = _recipient;
        paymentValue = _paymentValue;

        schedule();
    }

    function ()
        public payable 
    {
        if (msg.value > 0) { //this handles recieving remaining funds sent while scheduling (0.1 ether)
            return;
        } 

        process();
    }

    function process() public returns (bool) {
        payout();
        schedule();
    }

    function payout()
        private returns (bool)
    {
        require(block.number >= lockedUntil);
        require(address(this).balance >= paymentValue);

        recipient.transfer(paymentValue);

        emit PaymentExecuted(currentScheduledTransaction, recipient, paymentValue);
        return true;
    }

    function schedule() 
        private returns (bool)
    {
        lockedUntil = block.number + paymentInterval;

        currentScheduledTransaction = scheduler.schedule.value(0.1 ether)( // 0.1 ether is to pay for gas, bounty and fee
            this,                   // send to self
            "",                     // and trigger fallback function
            [
                1000000,            // The amount of gas to be sent with the transaction. Accounts for payout + new contract deployment
                0,                  // The amount of wei to be sent.
                255,                // The size of the execution window.
                lockedUntil,        // The start of the execution window.
                20000000000 wei,    // The gasprice for the transaction (aka 20 gwei)
                20000000000 wei,    // The fee included in the transaction.
                20000000000 wei,         // The bounty that awards the executor of the transaction.
                30000000000 wei     // The required amount of wei the claimer must send as deposit.
            ]
        );

        emit PaymentScheduled(currentScheduledTransaction, recipient, paymentValue);
    }
}

Básicamente, puede ver que la función de constructor es payable, lo que significa que debe financiar el contrato al crearlo. Esto financiará futuras llamadas recursivas.

Un buen ejemplo a tener en cuenta es también Reloj despertador recurrente . El proyecto es de código abierto y puedes echarle un vistazo al código.

Desinformación en otras respuestas/comentarios

Bueno, la otra respuesta no tiene en cuenta cómo funciona Ethereum Alarm Clock: esa llamada está programada, no se llama instantáneamente. Esto significa que no habrá un bucle infinito, es más como setIntervalen JavaScript.

Alguien también desinforma al comentar que hay gracePeriod, lo que significaría: "Encontrará un parámetro" gracePeriod "que dice que no puede hacer la misma llamada después de 255 bloques". - pero esto también está mal.

La documentación vinculada en sí está desactualizada, pero dice:

uint8 gracePeriod: la cantidad de bloques después de targetBlock que está bien ejecutar esta llamada. No puede ser inferior a 64. (predeterminado: 255).

Entonces, gracePeriod en este ejemplo se puede leer como VENTANA DE EJECUCIÓN.

¿Podría haber un problema de suposición de gas? Supongo que mientras "esta función sea capaz de aceptar fondos para gas", este contrato programado duraría para siempre.

@alpher ¿Pudiste verificar esto?
Según este documento. Encontrará un parámetro "gracePeriod" que dice que no puede hacer la misma llamada después de 255 bloques. Entonces, ¿no significa que hay un límite en recursivo?