Warum braucht es kein Gas, wenn die öffentliche Ansicht funktioniert, aber immer noch im Speicher geschrieben wird?

Ich habe vier Fragen. Ich hoffe ihr könnt mir helfen. Gute Ideenfragen, vielleicht hilft das anderen. Vielen Dank im Voraus.

Frage 1) Ich weiß, dass, wenn Sie nichts in den Speicher schreiben, diese Funktion gasfrei ist. Rechts? Ich kann sogar die öffentliche Ansicht zum Funktionieren bringen und Tausende für Schleifen erstellen, aber da es keinen Grund gibt, diese Änderung an andere Knoten zu verteilen, muss sie kostenlos sein, obwohl die For-Schleife groß ist und obwohl ich in dieser Funktion neue Variablen im Speicher erstelle. Ist meine Idee richtig?

Frage 2) Ich habe die öffentliche Ansichtsfunktion erstellt, aber in dieser Funktion habe ich so etwas wie das Schreiben einer Zahl in ein Array geschrieben und nach dem Schreiben habe ich ein neu hinzugefügtes Element aus diesem Array zurückgegeben. Ich habe den Speicher berührt, ich habe es dort geschrieben. aber weil ich meine Funktion "view" genannt habe, wurde ich nicht aufgefordert, Gas in die Metamaske zu geben. Es war überhaupt keine Metamaske erforderlich, obwohl ich im Speicher geschrieben habe. Warum? Meine Meinung ist, dass es für mich funktioniert, aber nicht für andere und es würde sich nicht über die Knoten ausbreiten.

Frage 3) Jeder sagt, dass Sie dynamische Arrays nicht von Funktionen zurückgeben können. Nehmen wir das Array uint[]. Es ist dynamisch, aber ich kann es trotzdem zurückgeben. was meinen die Leute dann? Ich weiß, dass ich kein mehrdimensionales Array und Array-Strukturen zurückgeben kann. aber ich kann uint[] zurückgeben.

Frage 4) Ich weiß, dass zum Beispiel einige Daten gespeichert sind uint[] x. Wenn ich jetzt so etwas in eine Funktion schreibe: uint[] memory mytest = x;Diese x Daten, die sich im Speicher befanden, werden in den Speicher kopiert. Habe ich recht? Wenn nicht? Warum? wenn ja, geht das umgekehrt? vom Speicher in den Speicher kopieren? Aber ich glaube nicht, weil Sie später nichts in den Speicher schreiben können, es sei denn, Sie geben es zur Laufzeit an.

Antworten (1)

  1. Ja.
  2. Wenn Sie eine Funktion aufrufen view, wird die Methode eth_callanstelle von verwendet eth_sendTransaction. Ein Aufruf wird lokal durchgeführt und alle Zustandsänderungen werden verworfen. Daher bleiben alle Schreibvorgänge in den Speicher, die Sie vorgenommen haben, einfach nicht bestehen.
  3. "Alle sagen, dass Sie dynamische Arrays nicht von Funktionen zurückgeben können." Dann ist "jeder" falsch. Wenn Sie eine Quelle angeben, könnte Ihnen vielleicht jemand helfen, herauszufinden, was gemeint war.
  4. Ja, das kopiert vom Speicher in den Speicher. Ja, der andere Weg geht auch:

    pragma solidity ^0.4.24;
    
    contract Test {
        uint256[] public foo;
    
        constructor() public {
            uint256[] memory bar = new uint256[](3);
            bar[0] = 1;
            bar[1] = 2;
            bar[2] = 3;
    
            foo = bar;
        }
    }
    
Die letzte Antwort, denken Sie, dass es richtig ist. Ich denke, es kopiert vom Speicher in den Speicher.
Richtig. Der Code in meinem Beitrag kopiert vom Speicher in den Speicher. Sie haben gefragt, ob der von Ihnen geteilte Code vom Speicher in den Speicher kopiert wurde. Ich sagte ja, das tut es. Dann hast du gefragt, ob es auch andersherum gehen könnte, und ich sagte, ja, das geht auch. Dann habe ich ein Beispiel gegeben.
1 ist falsch. Nicht nur das Schreiben in den Speicher kostet Gas, eine Transaktion, die nur eine Schleife enthält, verbraucht auch Gas
@TjadenHess Wir sprechen viewhier über Funktionen, die über eth_call(keine Transaktion) ausgeführt werden.
Ich sehe das nicht in der Frage, obwohl es impliziert sein könnte. viewFunktionen können auch über Transaktionen aufgerufen werden, z. B. durch einen anderen Vertrag, in diesem Fall kostet es immer noch Gas
Das ist richtig.