Ich möchte die Variable rewardsAmount verwenden, um meine Belohnungen zu berechnen:
uint Belohnungsbetrag = 0; // Nur hier kann ich Prämien abheben FunktiondrawRewards() onlyOwner external { require(rewardsAmount != 0); owner.transfer(rewardsAmount); Belohnungsbetrag = 0; } // Wenn der Vertrag keine Benutzergelder enthält, kann ich ihn zerstören Funktion kill() onlyOwner external { require(address(this).balance -rewardsAmount == 0); Selbstzerstörung (Eigentümer); } function someFunction() öffentlich { // etwas Code BelohnungenBetrag += 100; }
Wenn jemand Ether an die Vertragsadresse schickt, kann ich den Vertrag niemals beenden, richtig? Wie kann ich also verhindern, dass Ether an meinen Vertrag gesendet wird?
Nein, Sie können nicht verhindern, dass Ether an Ihren Vertrag gesendet wird.
Hüten Sie sich davor, eine Invariante zu codieren, die streng den Saldo eines Kontrakts prüft.
Ein Angreifer kann gewaltsam Ether an jedes Konto senden und dies kann nicht verhindert werden (auch nicht mit einer Fallback-Funktion, die ein revert() ausführt).
Der Angreifer kann dies tun, indem er einen Vertrag erstellt, ihn mit 1 Wei finanziert und selfdestruct(victimAddress) aufruft. In VictimAddress wird kein Code aufgerufen, daher kann dies nicht verhindert werden. Dies gilt auch für die Blockbelohnung, die an die Adresse des Miners gesendet wird, die eine beliebige Adresse sein kann.
Da Vertragsadressen auch vorberechnet werden können, kann Ether an eine Adresse gesendet werden, bevor der Vertrag bereitgestellt wird.
Siehe SWC-132
Sie können Gelder, die an eine Vertragsadresse überwiesen werden, nicht zuverlässig ablehnen. Achten Sie darauf, keinen Angriffsvektor zu erstellen (Ihr zu deaktivieren selfdestruct
), da selfdestruct(yourContract)
Ihnen jemand den Fehler zeigen wird. Autsch!
Ein obskurerer Weg ist ein bisschen wie eine Ostereiersuche, aber nicht zu weit hergeholt. Bei einer Deployer-Adresse und einer Nonce ist die Adresse des bereitgestellten Vertrags vorhersehbar , sodass es möglich ist, einen positiven Saldo zu haben , bevor der Vertrag bereitgestellt wird . Es ist nützlich für esoterische Muster, Unfug und mögliche Sabotage, wenn Ihr Vertrag wieder address(this).balance
für wichtige Logik verwendet wird. Denken Sie daran, dass es möglicherweise nicht das ist, was Sie erwarten.
Mir ist klar, dass es sich um ein erfundenes Beispiel handelt. Die wirkliche Gefahr besteht hier darin, address(this).balance
Logik zu verwenden. Zum Wohle aller anderen, die darauf stoßen, würde ich selfdestruct
generell davon abraten. Selbstzerstörung ist ein Bug .
Ich hoffe es hilft.
fy
Rob Hitchens
onlyIfRunning
und er sollterequire(!pause, "the contract is stopped.")
.Rob Hitchens
fy