Kamikaze-Verträge

Beim Zusammenstellen eines einfachen Vertrages über Remix mit dem neuesten Nightly erhalte ich die folgende Warnung

"Die Verwendung von Selbstzerstörung kann aufrufende Verträge unerwartet blockieren. Seien Sie besonders vorsichtig, wenn dieser Vertrag von anderen Verträgen verwendet werden soll (z. B. Bibliotheksverträge, Interaktionen). Die Selbstzerstörung des aufgerufenen Vertrags kann Anrufer in einen funktionsunfähigen Zustand versetzen."

„Mehr“ führt hier hin , über den berüchtigten Parity-Multi-Sig-Wallet-Bug (Pmswb).

Was meine Aufmerksamkeit auf sich gezogen hat, ist die Erwähnung von Wechselwirkungen.

Kann die Interaktion mit einem selfdestructingVertrag (beachten Sie das fortlaufende -ing) meinen Vertrag in einen nicht funktionsfähigen Zustand versetzen? Wohlgemerkt, ich spreche hier nicht von Bibliotheken (das war das Pmswb-Szenario), aber ist die Unterscheidung zwischen der Nutzung einer Bibliothek und der Interaktion mit einem Vertrag in Ethereum sinnvoll?

Was ich im Sinn habe, ist ein Vertrag, mit dem ich eine Transaktion durchführe, die sich aus irgendeinem Grund (böswillig oder nicht) selbst zerstört und meinen Vertrag funktionsunfähig macht. Ist das ein mögliches/realistisches Szenario? Wenn ja, ist das nicht ein sehr ernstes Problem?

Antworten (1)

Diese Warnung sagt Ihnen, dass Sie vorsichtig sein sollten, wenn Sie Ihren Vertrag einsetzen, der sich selbst zerstören kann, und dass andere Verträge davon abhängen.

Wenn Sie Vertrag B haben, der eine Funktion für Vertrag A aufruft, und Vertrag A selbstzerstört ist, funktioniert Vertrag B nicht mehr.


Wenn Sie einen Vertrag mit einer Funktion haben, die sich selbst zerstört, gibt es zwei mögliche Dinge, die passieren könnten, wenn diese Funktion von einem anderen Vertrag aufgerufen wird. Angenommen, Sie haben Vertrag A wie folgt:

contract A {
    address public owner = msg.sender;

    function bye() public{
        selfdestruct(owner);
    }
}

und Vertrag B:

contract B {

    uint public data = 34;

    function killContractA(address _a) public {
        A a = A(_a);
        a.bye();
    }

    function killMyself(address _a) public {
        _a.delegatecall(bytes4(keccak256("bye()")));
    }
}

Wenn Vertrag B (der von jedem anderen bereitgestellt werden kann) killContractA() aufruft, wird dies effektiv dazu führen, dass sich Ihr Vertrag A selbst zerstört.

Wenn Vertrag B killMyself() aufruft, wird er selbst zerstört, vorausgesetzt, er verwendet den Delegataufruf.

Aus diesem Grund sollten Sie Delegatecall niemals verwenden, um auf einen Vertrag abzuzielen, von dem Sie nichts wissen.

In beiden Fällen könnten Sie dieses Verhalten verhindern, indem Sie verlangen, dass der msg.sender der Eigentümer des Vertrags in Vertrag A ist.

Danke für deine Antwort. Sie haben geschrieben: "Wenn Sie Vertrag B haben, der eine Funktion für Vertrag A aufruft, und Vertrag A sich selbst zerstört, funktioniert Vertrag B nicht mehr." Wenn ich also einen Vertrag anrufe, der einen Fehler oder bösartigen Code enthält, kann dies meinen Vertrag deaktivieren. Dies ist, was ich als ein sehr ernstes Problem bezeichnet habe. Wenn ich nur Verträge aufrufen kann, die ich kenne und denen ich vertraue, ist der gesamte Zweck von Ethereum, zumindest nach meinem Verständnis, ernsthaft eingeschränkt.
Das würde ich nicht sagen. Auf welcher anderen Plattform können Sie den Code anderer Personen in der Produktion frei verwenden, um darauf aufzubauen? Wenn Sie etwas auf den Vertrag eines anderen aufbauen möchten, sollten Sie den Code lesen und sicherstellen, dass er Ihrem eigenen Vertrag nicht schadet. Es ist nicht anders, als sich auf eine Drittanbieter-API zu verlassen, die, wenn sie nicht mehr funktioniert oder heruntergefahren wird, Ihre App nicht mehr funktioniert.
Ich bin nicht einverstanden. Es ist eher eine Situation, in der, wenn ich einen Server anrufe, egal wie sicher mein Code ist, er meinen Computer für immer deaktivieren kann. Was meine Frage betrifft, ist die Antwort jedoch klar.
Außerdem scheint es ein Missverständnis aus Ihrem vorherigen Kommentar zu geben. Wenn Sie "einen Vertrag aufrufen, der einen Fehler oder bösartigen Code enthält, kann dies meinen Vertrag deaktivieren". Wenn wir insbesondere über den Aufruf einer Funktion sprechen, die sich selbst zerstört, würde Ihr eigener Vertrag nur zerstört, wenn Sie diese Funktion mit Delegatecall aufgerufen hätten (was Sie nicht tun sollten, es sei denn, Sie haben einen sehr guten Grund dafür).
Wenn dies nicht der Fall ist, würde Ihr Vertrag, der von Vertrag A abhängt, brechen, wenn Vertrag A nicht mehr funktioniert. Genauso wie Ihre Website nicht mehr richtig funktioniert, wenn sie von der Facebook-API abhängt und sie sie plötzlich ändern oder herunterfahren.