DEV Community

Cover image for Einsatz von transfer oder send und das Out-of-Gas-Problem
THE CODE DOCTOR
THE CODE DOCTOR

Posted on

Einsatz von transfer oder send und das Out-of-Gas-Problem

Ja, in Solidity kann es beim Einsatz von transfer oder send zu einem Out-of-Gas-Problem kommen, besonders wenn der Empfänger ein Smart Contract ist, der teure Operationen in seiner fallback- oder receive-Funktion ausführt.

Erklärung des Problems:

  • transfer und send sind beides Methoden, um Ether an einen anderen Account zu schicken.
  • Sie schicken standardmäßig 2300 Gas mit, um den Empfang zu ermöglichen. Das ist normalerweise genug, um eine einfache fallback- oder receive-Funktion auszuführen.
  • Falls der Empfänger aber mehr als diese 2300 Gas benötigt, schlägt die Transaktion fehl.

Beispiel:
Angenommen, du hast einen Smart Contract, der Ether an einen anderen Vertrag sendet. Wenn der Empfängervertrag in seiner fallback-Funktion eine komplexe Operation hat, könnte der Gasverbrauch über 2300 Gas liegen, was zu einem Out-of-Gas-Fehler führt.

Beispiel Smart Contract:

// Vertrag A sendet Ether an Vertrag B
contract A {
    function sendEther(address payable _to) public payable {
        // Versucht, 1 Ether zu senden
        _to.transfer(1 ether); // Oder _to.send(1 ether);
    }
}

// Vertrag B hat eine teure fallback-Funktion
contract B {
    // Diese Funktion wird bei Empfang von Ether aufgerufen
    fallback() external payable {
        // Hier wird eine teure Operation durchgeführt
        for (uint i = 0; i < 1000; i++) {
            // Komplexer Rechenaufwand
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Was passiert hier:

  1. Vertrag A versucht, Ether an Vertrag B zu senden.
  2. Vertrag B hat eine fallback-Funktion, die teure Rechenoperationen ausführt.
  3. transfer schickt nur 2300 Gas mit, aber die fallback-Funktion in Vertrag B braucht mehr Gas, um die Schleife durchzuführen.
  4. Da 2300 Gas nicht ausreichen, schlägt die Transaktion fehl und es kommt zu einem Out-of-Gas-Fehler.

Lösung:
Um das zu vermeiden, kann man statt transfer oder send die Funktion call verwenden, die es ermöglicht, mehr Gas mitzuschicken:

// contract A sends Ether using call with more gas
contract A {
    function sendEtherWithCall(address payable _to) public payable {
        (bool success, ) = _to.call{value: 1 ether}(""); // Unbegrenztes Gas
        require(success, "Transfer failed.");
    }
}
Enter fullscreen mode Exit fullscreen mode

Mit call kannst du beliebig viel Gas mitgeben, sodass der Empfänger genug Gas für seine Operationen hat.

Zusammenfassen gehen beim Out-of-Gas-Fehler keine Gelder verloren – nur das verbrauchte Gas.

  • Der Ether bleibt sicher beim Sender (Vertrag A).
  • Der Absender trägt nur die Gasgebühren, die während des Versuches aufgebraucht wurden.
  • Der Empfänger (Vertrag B) erhält keinen Ether, da die Transaktion nicht erfolgreich war und zurückgerollt wurde.

Top comments (0)