Gibt es einen Fehler in meinem Soliditätsvertrag?

Stellen Sie sich einen einfachen Vertrag vor, der Eth sammelt. Gibt es eine Möglichkeit, dies so zu manipulieren, dass, nachdem Benutzer Geld gesendet haben, this.balance =/= max_val? Kann dies so gespielt werden, dass isFinished() niemals über die require-Anweisung hinauskommt?

uint max_val = 3 * 10** 18; // Can send up to 3 ETH
bool finished = false; // Not finished

// Function to send ETH
function sendEth() payable {
    require(!finished); // Cannot be over
    require(this.balance <= max_val);  // Contribution must be less than or equal to contribution max
}

// Function to finish sending
function isFinished() {
    require(!finished); // Cannot be finished. Cannot be called twice.
    require(this.balance == max_val);  // Must have collected max ETH
    finished = true;
}

Antworten (2)

Vorab ein paar Anmerkungen:

  1. Warum heißt die Funktion, die Ether empfängt, sendEth, sollte sie nicht aufgerufen werden, receiveEthweil sie das tut?
  2. Warum nicht Modifikatoren verwenden, die Ihren Code deutlich verständlicher machen? Leicht verständlicher Code == weniger fehlerhafter Code.

Meine Vermutung ist, dass das Gleichgewicht nach der Funktion aktualisiert wird, aber ich bin mir nicht sicher (siehe Kommentar unten).

pragma solidity ^0.4.11;

contract Testing {

    uint max_val = 3 * 10 ** 18;
    bool finished = false;

    modifier notFinished() {
       if (finished)
           revert();
       _;
    }

    // NOTE: Not sure if this.balance is already updated with
    // the new msg.value (my guess is no). I will edit this code
    // if someone corrects me.
    function receiveEth() notFinished() payable {

       // If the tx would go over max, revert
       if (msg.value + this.balance > max_val)
           revert();

       // If we will have exactly max, we're done
       if (msg.value + this.balance == max_val)
           finished = true;

       // Otherwise, accept the eth
    }
}

Nach Ihrem Code zu urteilen, ist es trivial, mehr als zu senden, max_valweil Sie nicht prüfen, ob msg.valuemehr als ist max_value - this.balance. Sie müssen require(msg.value <= max_value - this.balance)innen hinzufügen sendEth().

Ich verstehe, dass genau dann, wenn sendEth()aufgerufen this.balancewird, aktualisiert wird, bevor Zeilen der Funktion durchlaufen werden. Wenn dies der Fall ist, wäre es dann nicht require(msg.value <= max_value - this.balance)überflüssig?
Ich glaube, dass das Gleichgewicht danach aktualisiert wird, aber ich kann das in den Dokumenten nicht finden.