Solidity speichert den Speicherzeiger in der Speichervariable, um von unterschiedlichen Funktionen aus darauf zuzugreifen

Ist es in einem Vertrag mit Solidity möglich, einen Zeiger auf eine Speichervariable in einer Speichervariablen (oder an einer anderen geeigneten Stelle) zu speichern und von verschiedenen Funktionen aus darauf zuzugreifen?

Betrachten Sie das folgende Beispiel in Solidity-Pseudocode:

contract AContract {

    struct AStruct { 
      uint a_field;
    }

    AStruct variable_a;
    AStruct variable_b;

    AStruct storage pointer_to_either_a_or_b;

    modifier AModifier()
    {
      if (condition_a)
      {
        pointer_to_either_a_or_b = variable_a;
      }
      else
      {
        pointer_to_either_a_or_b = variable_b;
      }
    }

    function AFunctionUsingPointerToAorB100() internal AModifier()
    {
      pointer_to_either_a_or_b.a_field = 100;          
    }

    function AFunctionUsingPointerToAorB200() internal AModifier()
    {
      pointer_to_either_a_or_b.a_field = 200;          
    }

}

Immer wenn ich versuche, das Schlüsselwort "storage" für eine Speichervariable zu verwenden, erhalte ich den folgenden Kompilierungsfehler für "AStruct storage pointer_to_either_a_or_b":

Fehler: Erwarteter Bezeichner, "Storage" erhalten

Gibt es eine Möglichkeit, dies zu umgehen, z. B. den Zeiger an einer anderen Stelle im Code zu platzieren?

Zustandsvariablen sind IMMER Speichervariablen, also können Sie das nicht zu AStruct storage pointer_to_either_a_or_b hinzufügen; Erklärung. Es ist bereits eine Speichervariable.

Antworten (1)

Das Entfernen des Schlüsselworts storage at AStruct storage pointer_to_either_a_or_b;würde den Fehler beheben (da state-Variablen immer storage sind), aber Sie werden nicht in der Lage sein, das zu erreichen, was Sie zu tun versuchen.

Der Grund ist; Da AStruct pointer_to_either_a_or_b;es sich um eine Speichervariable handelt, wird durch Zuweisen eines Werts eine unabhängige Kopie erstellt, kein Verweis auf variable_aoder . Es wird hiervariable_b in den Solidity-Dokumenten erwähnt .

Zuweisungen zwischen Speicher und Speicher und auch zu einer Zustandsvariablen ( auch von anderen Zustandsvariablen ) erzeugen immer eine unabhängige Kopie.

Ich weiß nicht, was Ihre tatsächliche Anforderung ist, aber je nachdem, was Sie hier gepostet haben, werde ich keinen Modifikator (und keine Zeiger) verwenden, sondern so etwas versuchen,

function sample(uint _val) public // val = 100 or 200
 {
      if (condition_a)
      {
        variable_a.a_field = _val;
      }
      else
      {
        variable_b.a_field = _val;
      }
}

Hoffe das hilft!

FYI: Wie ich weiß, sind lokale Variablen, die in Modifikatoren deklariert sind, innerhalb der Funktion nicht zugänglich.

Danke für Ihre Antwort. Ich vermutete, dass es nicht möglich wäre, innerhalb unterschiedlicher Funktionen auf einen gemeinsam genutzten a-Zeiger auf eine Speichervariable zuzugreifen. Die eigentliche Anforderung besteht darin, einen Satz vieler Funktionen zu haben, die abhängig von einer bestimmten Bedingung eine bestimmte Variable als Ausgabe auswählen. Ich dachte an Modifikatoren als eine hypothetisch gute Option zum Erstellen eines Zeigers auf diese Ausgabevariablen, aber wie Sie sagten, ist es nicht möglich, auf Variablen zuzugreifen, die in Modifikatoren innerhalb von Funktionen deklariert sind.
Ich werde wahrscheinlich etwas Ähnliches wie Ihren Vorschlag verwenden müssen, indem ich eine zusätzliche Funktion verwende, um einen Zeiger zurückzugeben: function Greeter_a(uint _val) public // val = 100 or 200 { GetPointer().a_field = _val; } (...) Funktion Greeter_x(uint _val) public // val = 100 oder 200 { GetPointer().x_field = _val; } function GetPointer() öffentliche Rückgaben (VariableType-Speicherung) { if (condition_a) { return variable_a; } Else { Rückgabevariable_b; } }
Ich fürchte, Sie können dies mit tun, getPointer()da der zurückgegebene Wert eine Kopie der Variablen ist und nicht auf die Zustandsvariable zeigt und diese ändert
Wenn das Schlüsselwort „storage“ zu „returns“ hinzugefügt wird, gibt es tatsächlich einen Verweis auf die Speichervariable zurück, wie einen Zeiger. "Returns (VariableType storage)" scheint also zu funktionieren.