Verständnis des Aufrufs im Stil von nameReg.call("register", "MyName") zwischen Verträgen

Hier ist ein Beispiel aus Solidity- Dokumenten zu Adresstypmethoden ( speziell Methode):call

Adresse nameReg = 0x72ba7d8e73fe8eb666ea66babc8116a41bfb10e2;

nameReg.call("registrieren", "MeinName");

nameReg.call(bytes4(sha3("fun(uint256)")), a);

Ich kann nicht verstehen, was die zweite Zeile tut. Ruft es die Fallback-Funktion mit diesen beiden Argumenten auf? Oder übergibt es die Zeichenfolge MyName an das Funktionsregister im NameReg- Vertrag?

Antworten (2)

Aus dem Link in der Frage ist der wichtige Teil über nameReg.call("register", "MyName")(fett gedruckte Mine):

Um eine Schnittstelle mit Verträgen herzustellen, die nicht dem ABI entsprechen , wird die Funktion callbereitgestellt, die eine beliebige Anzahl von Argumenten beliebigen Typs entgegennimmt. Diese Argumente werden auf 32 Bytes aufgefüllt und verkettet.

Siehe Hinweis hier :

Hinweis: Die ABI ist eine Abstraktion, die nicht Teil des Ethereum-Kernprotokolls ist. Jeder kann seinen eigenen ABI für seine Verträge definieren, und alle Aufrufer solcher Verträge müssten diesen ABI einhalten, um aussagekräftige Ergebnisse zu erhalten. Es ist jedoch für alle Entwickler einfacher, Solidity, Serpent und web3.js zu verwenden, die alle der oben genannten ABI entsprechen.

nameReg.call("register", "MyName") wird sich nicht registerauf einen nameRegvon Solidity erstellten Vertrag berufen. Der Grund dafür ist, dass Solidity "register" nicht verwendet, um "Funktionen" nachzuschlagen (es verwendet die ersten 4 Bytes als Methoden-ID. Zum Beispiel EVM-Pseudocode, den Solidity produziert, siehe hier ). Hier ist Code für einen schnellen Test :

contract NameReg {
    bytes32 public nn;
    bytes public calldata;

    function register(bytes32 name) {
      nn = name;    
    }

    function() {
        calldata = msg.data;
    }

    function doesNotCallRegister() {
        this.call("register", "MyName");
    }
 }

Mit einem nameRegvon Solidity kompilierten Vertrag nameReg.call("register", "MyName")wird die Fallback-Funktion aufgerufen, in der msg.data"register", "MyName" auf 32 Bytes aufgefüllt und verkettet wird: 0x72656769737465720000000000000000000000000000000000000000000000004d794e616d650000000000000000000000000000000000000000000000000000.

Fallback-Funktion speichert msg.data in calldata. Mutiert es den Staat? Reichen 2300 Gas dafür, wenn die Fallback-Funktion aufgerufen wird?
@kk-dev11 Ja, die Fallback-Funktion mutiert in diesem Fall zum Zustand und kostet mehr als 2300 Gas. Aber das Aufrufen nameReg.call("register", "MyName")wird mehr Gas geben: es ist ein .callund siehe Fall 2 von ethereum.stackexchange.com/a/5993/42

Dieses Code-Snippet baut auf einem der Beispielverträge auf der Seite Verträge in der Solidity-Dokumentation auf:

contract NameReg {
    function register(bytes32 name);
    function unregister();
}

So:

Oder übergibt es die Zeichenfolge MyName an das Funktionsregister im NameReg-Vertrag?

Ja.