was sind die unterschiede zw .anrufen und. ?

 contract GatekeeperOne {

  address public entrant;

  modifier gateOne() {
    require(msg.sender != tx.origin);
    _;
  }

  modifier gateTwo() {
    require(msg.gas % 8191 == 0);
    _;
  }

  modifier gateThree(bytes8 _gateKey) {
    require(uint32(_gateKey) == uint16(_gateKey));
    require(uint32(_gateKey) != uint64(_gateKey));
    require(uint32(_gateKey) == uint16(tx.origin));
    _;
  }

  function enter(bytes8 _gateKey) public gateOne gateTwo gateThree(_gateKey) returns (bool) {
    entrant = tx.origin;
    return true;
  }
}


contract test{
GatekeeperOne public t;
function test()public payable{
    t = GatekeeperOne(0x5c3c1540dfcd795b0aca58a496e3c30fe2405b07);

}
function attack()public payable{
    t.call.gas(41171)(bytes4(keccak256("good(bytes8)")), 0x123);
}
function attack2()public payable{
    t.enter(0x123);
}
function()public payable{}

}

Wenn ich den Angriff () ausführe , wird es erfolgreich sein. Und attack2() wird fehlschlagen. die Fehlermeldung:

Transaktion zu test.attack2Fehler:

VM-Fehler: Zurücksetzen. revert Die Transaktion wurde in den Ausgangszustand zurückgesetzt. Hinweis: Der Konstruktor sollte zahlbar sein, wenn Sie einen Wert senden. Debuggen Sie die Transaktion, um weitere Informationen zu erhalten.

Einer ruft eine Funktion namens auf goodund der andere ruft eine Funktion namens auf enter... Ich bin mir nicht sicher, warum sie überhaupt dasselbe tun würden.

Antworten (1)

Wie bereits von smarx gesagt, rufen Sie zwei verschiedene Funktionen auf, daher verhalten sie sich unterschiedlich.

Zu der Frage im Titel:

Einen Einblick in den Unterschied zwischen <address>.callund <address>.<function>aus der Dokumentation von Solidity erhalten Sie in Abschnitt 4.4.4 (Seite 68) bzw. in Abschnitt 4.4.5 (Seiten 70-71).

<address>.call

<address>.call(bytes memory) returns (bool): Low-Level-CALL mit der gegebenen Nutzlast ausgeben, bei Fehler falsch zurückgeben, alles verfügbare Gas weiterleiten, einstellbar

<address>.function

Funktionsaufrufe verursachen Ausnahmen, wenn der aufgerufene Vertrag nicht existiert (in dem Sinne, dass das Konto keinen Code enthält) oder wenn der aufgerufene Vertrag selbst eine Ausnahme auslöst oder das Gas ausgeht

Abschluss

Ersteres ist also Low-Level in dem Sinne, dass Sie den Rückgabewert manuell überprüfen müssen, während das Zweite die Ausnahme sprudeln lässt (höher ist).