DEV Community

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

Posted on

1

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.

Postmark Image

Speedy emails, satisfied customers

Are delayed transactional emails costing you user satisfaction? Postmark delivers your emails almost instantly, keeping your customers happy and connected.

Sign up

Top comments (0)

Image of Docusign

🛠️ Bring your solution into Docusign. Reach over 1.6M customers.

Docusign is now extensible. Overcome challenges with disconnected products and inaccessible data by bringing your solutions into Docusign and publishing to 1.6M customers in the App Center.

Learn more