Kann ich direkte Transaktionen an Smart-Contract-Adressen deaktivieren?

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?

Antworten (2)

Nein, Sie können nicht verhindern, dass Ether an Ihren Vertrag gesendet wird.

Denken Sie daran, dass Ether zwangsweise an ein Konto gesendet werden kann

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

Quelle: https://consensys.github.io/smart-contract-best-practices/recommendations/#remember-that-ether-can-be-forced-sent-to-an-account

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).balancefü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).balanceLogik zu verwenden. Zum Wohle aller anderen, die darauf stoßen, würde ich selfdestructgenerell davon abraten. Selbstzerstörung ist ein Bug .

Ich hoffe es hilft.

Vielen Dank! Also muss ich "function pause() onlyOwner { pause = true }" verwenden? Und ich verstehe diesen Teil nicht, "weil sich jemand (Ihr Vertrag) selbst zerstören wird, um Ihnen den Fehler zu zeigen." Wo kann ich mehr darüber lesen?
Ja. Es ist normalerweise besser, alle Funktionen einzufrieren, anstatt sich selbst zu zerstören. Sie benötigen auch einen Modifikator, onlyIfRunningund er sollte require(!pause, "the contract is stopped.").
Ihr Vertrag hat die Selbstzerstörung verwendet, um das Geld an den Eigentümer zu senden. Jemand anderes kann seinen Vertrag selbst zerstören, um Geld in Ihren Vertrag zu zwingen , und das kann nicht abgestoßen werden - die ursprüngliche Frage (Titel), also nein, das können Sie nicht. Nicht 100% zuverlässig, also ...
Jetzt verstehe ich)) Nochmals vielen Dank, ich habe viel gelernt.