Was passiert, wenn Sie mit dem Ethereum Alarm Clock Scheduler einen rekursiven Zeitplanaufruf tätigen?

Mein Ziel ist es, einmal täglich einen Anruf zu vereinbaren.

[F] Ist es möglich, die rekursive Funktion zu verwenden, um einen Anruf einmal täglich mit dem Ethereum-Wecker-Scheduler zu planen?

Beispiel aus folgender Antwort 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.
    } }

CallMeLater();Ich habe am Ende der Funktion eine zusätzliche Funktion hinzugefügt callback(), nehme ich an, die einen neuen Zeitplan (1 Tag im Voraus) erstellen wird, um anzurufen callback().

Antworten (2)

Lösung

Das Protokoll hat sich seit der Veröffentlichung der Frage geändert. Es ist möglich, rekursive Anrufe zu tätigen, indem ein Dienst aufgebaut wird, der beispielsweise die Proxy-Brieftasche nutzt (um nachfolgende Anrufe zu finanzieren).

Ethereum Alarm Clock hat ein RecurringPayment-Beispiel in seinem Repository. Das ist der Vertrag:

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);
    }
}

Grundsätzlich können Sie sehen, dass die Konstruktorfunktion payable, dh Sie müssen den Vertrag bei der Erstellung finanzieren. Dies wird zukünftige rekursive Aufrufe finanzieren.

Ein gutes Beispiel ist auch Recurring Alarm Clock . Das Projekt ist Open Source und Sie können sich den Code ansehen.

Fehlinformationen in anderen Antworten/Kommentaren

Nun, die andere Antwort berücksichtigt nicht, wie Ethereum Alarm Clock funktioniert - dieser Anruf wird geplant, nicht sofort angerufen. Das heißt, es gibt keine Endlosschleife, es ist eher wie setIntervalin JavaScript.

Jemand gibt in einem Kommentar auch falsch an, dass es gracePeriod, was bedeuten würde: "Sie finden einen Parameter "gracePeriod", der besagt, dass Sie nach 255 Blöcken nicht denselben Anruf tätigen können." - aber auch das ist falsch.

Die verlinkte Dokumentation selbst ist veraltet, aber sie sagt:

uint8 gracePeriod: Die Anzahl der Blöcke nach targetBlock, die es noch in Ordnung ist, diesen Aufruf auszuführen. Darf nicht kleiner als 64 sein. (Standard: 255).

GracePeriod kann in diesem Beispiel also als AUSFÜHRUNGSFENSTER gelesen werden.

Könnte es ein Problem mit der Gasannahme geben? Ich schätze, solange "diese Funktion in der Lage ist, Geld für Gas anzunehmen", würde dieser geplante Vertrag für immer laufen.

@alpher Konntest du das überprüfen?
Laut diesem Dokument. Sie finden einen Parameter "gracePeriod", der besagt, dass Sie nach 255 Blöcken nicht denselben Anruf tätigen können. Bedeutet das nicht, dass es eine Grenze in der Rekursion gibt?