Zeitreihenfolge beim Aufrufen von Funktionen von Smart Contracts

Wie kann ich überprüfen, ob der Miner tatsächlich die richtige Reihenfolge von Smart Contracts-Funktionsaufrufen ausführt, wenn eine Notwendigkeit von Bestellungen besteht?

Deklarieren Sie sie alle privateund stellen Sie eine einzelne publicFunktion bereit, die sie in der gewünschten Reihenfolge ausführt. Alternativ können Sie Ihrem Vertrag eine Zustandsvariable hinzufügen ( enumideal für diesen Zweck) und diese verwenden, um eine Zustandsmaschine zu implementieren. In jeder Funktion requirewird diese Variable zu Beginn der Funktion auf einen bestimmten Wert gesetzt und am Ende der Funktion auf den nächsten Wert geändert.

Antworten (1)

Sie können nicht sicherstellen, dass die Miner Transaktionen in der beabsichtigten Reihenfolge akzeptieren, aber Sie können überprüfen und ablehnen, wenn dies nicht der Fall ist. Sie würden jede neue Transaktion von etwas früherem abhängig machen.

Hier verwende ich nur einen einfachen Zähler.

pragma solidity 0.5.1;

contract Ordered {

    uint public nonce;

    event LogNextTransaction(address sender, uint transactionNumber);

    function doSomethingOrdered(uint transactionNumber) public {
        require(transactionNumber == nonce);
        emit LogNextTransaction(msg.sender, transactionNumber);
        nonce++;
    }
}

Diese Methode ist insofern locker, als jeder Teilnehmer beim nächsten Nonce einfach raten kann, ohne zu wissen, was davor war (weil es nur zählt). Sie können Absender zeigen lassen, dass sie Kenntnis von der vorherigen Transaktion haben, indem Sie die Anforderung so formulieren, dass sie nicht (leicht) erraten können. Es gibt eine nicht offensichtliche Möglichkeit, eine Wettlaufbedingung zu schaffen, wenn die Sender konkurrieren. Fragen Sie mich nach Details, wenn Sie das Gefühl haben, dass dies relevant sein könnte.

pragma solidity 0.5.1;

contract Ordered {

    bytes32 public lastHash;

    event LogNextTransaction(address sender, bytes32 txnHash);

    function doSomethingOrdered(bytes32 thisHash) public {
        bytes32 testHash = hashHelper(lastHash, msg.sender);
        require(testHash == thisHash);
        emit LogNextTransaction(msg.sender, testHash);
        lastHash = testHash;
    }

    // convenience function helps clients compute needed hashes
    function hashHelper(bytes32 hash, address sender) public pure returns(bytes32) {
        return keccak256(abi.encodePacked(hash, sender));
    }
}

Ich hoffe es hilft.