Wann man "View" und "Pure" anstelle von "Constant" verwendet [duplizieren]

Laut Solidity 0.4.17 Release Notes

Diese Version überprüft endlich die Modifikatoransicht (früher Konstante genannt) und reine On-Funktionen. Verwenden Sie als Faustregel view, wenn Ihre Funktion den Speicher nicht ändert, und pure, wenn sie nicht einmal Statusinformationen liest - aber der Compiler schlägt auch selbst die engste Einschränkung vor.

Was bedeutet das in der Praxis?

Antworten (4)

In früheren Versionen haben wir den constantModifikator angewendet, um anzuzeigen, dass eine Funktion den Speicherstatus in keiner Weise ändert. Zum Beispiel:

pragma solidity 0.4.16; 

contract UseConstant {

    string greeting;

    function UseConstant() public {
        greeting = "Hello";
    }

    function SayHello() public constant returns(string says) {
        return greeting;
    }
}

constantgibt an, dass keine Netzwerküberprüfung erforderlich ist. Aufrufer erhalten returnWerte (schnell, aus lokaler Speicherung und Verarbeitung) anstelle von Transaktions-Hashes.

Beginnend mit solc 0.4.17 constantwird zugunsten von zwei neuen und spezifischeren Modifikatoren abgewertet.

Ansicht Dies ist im Allgemeinen der Ersatz für constant. Es zeigt an, dass die Funktion den Speicherzustand in keiner Weise verändert.

Pure Dies ist noch restriktiver und zeigt an, dass es nicht einmal den Speicherstatus liest.

Eine pureFunktion könnte in etwa so aussehen wie in diesem sehr konstruierten Beispiel:

function returnTrue() public pure returns(bool response) {
    return true;
}

In Remix erhalten Sie eine Warnung, wenn Sie den alten constantModifikator verwenden. Es untersucht den Funktionscode und zeigt die maximale Einschränkung an, die Sie sicher anwenden können.

Ich hoffe es hilft.

AKTUALISIEREN

Dies ist eine beliebte Frage und Antwort, daher habe ich beschlossen, sie in einem ausführlicheren Medium-Beitrag näher auszuführen: https://blog.b9lab.com/calls-vs-transactions-in-ethereum-smart-contracts-62d6b17d0bc2

Der constantModifikator hat die Bedeutung, dass die Funktion den Vertragsspeicher nicht ändert (aber das Wort Konstante hat nicht wirklich die Bedeutung vermittelt, für die es verwendet wird).

Die neuen Ersetzungen für constantnach der Veröffentlichung von Solidity 0.4.17 , viewund pure, vermitteln die Bedeutung ihrer Verwendung.


viewkann als Teilmenge betrachtet constantwerden, die den Speicher liest (daher Anzeige). Der Speicher wird jedoch nicht geändert.

Beispiel:

contract viewExample {

    string state;

    // other contract functions

    function viewState() public view returns(string) {
        //read the contract storage 
        return state;
    }
}

purekann als Teilmenge betrachtet werden, constantbei der der Rückgabewert nur durch seine Parameter (Eingabewerte) bestimmt wird. Es findet kein Lese- oder Schreibzugriff auf den Speicher statt und es werden nur lokale Variablen verwendet (hat das Konzept reiner Funktionen in der funktionalen Programmierung).

Beispiel:

contract pureExample {

    // other contract functions

    function pureComputation(uint para1 , uint para2) public pure returns(uint result) {
        // do whatever with para1 and para2 and assign to result as below
        result = para1 + para2;
        return  result;
    }

}

Um diese pureoder viewFunktionen von außen auszuführen/aufzurufen, wird keine Transaktion benötigt. Nur a callreicht aus, da der Zustand der Blockchain durch den Aufruf dieser nicht verändert wird. Daher wird kein Gas/Äther benötigt, um diese Funktionen von außen zu nutzen.

Interne Aufrufe dieser Funktionen können jedoch Gas kosten, wenn der interne Aufruf von einer Transaktion stammt. Weitere Einzelheiten darüber, wie interne Anrufe zu diesen Gas kosten können, finden Sie hier .

Angenommen, Sie haben eine Funktion wie diese in der SafeMath-Bibliothek:

function add(uint256 x, uint256 y)
    internal pure
    returns(uint256) {
        uint256 z = x + y;
        assert((z >= x) && (z >= y));
        return z;
    }

Hier wird kein Zustand gelesen.

Wohingegen

String something;

    function tellMeSomething() returns (string whatever){
    whatever = something;
    }

würde auf den Speicher zugreifen. Meine Vermutung ist, dass im ersten Fall beim Kompilieren des Vertrages keine Opcodes zum Auslesen des Zustandes in irgendeiner Weise implementiert werden müssen, wie es im zweiten Beispiel der Fall wäre. Dies sollte meiner Meinung nach während des Einsatzes Gas sparen.

Wenn eine Solidity-Funktion in den Speicher schreibt , z. B.: sendTokenTo(John), hat sie keines dieser Labels. (Diese Funktion schreibt in den Speicher, weil sie das Token-Guthaben von jemandem in der Blockchain ändern muss.) Das ist, was Sie gewohnt sind. Zweitens, wenn eine Funktion einfach aus dem Speicher liest, aber nichts in den Speicher schreibt, z. B.: getTokenBalance(John), ist dies eine Ansichtsfunktion . Wenn eine Funktion keinen Speicher liest oder schreibt, handelt es sich schließlich um eine reine Funktion, z. B.: onePlusOne().

Die Verwendung von Pure- und View-Funktionen ermöglicht es diesen Funktionen, kein Gas zu verbrauchen , da sie den Zustand nicht ändern. Das Aufrufen dieser Funktionen mit so etwas wie web3.js führt dazu, dass diese Pure/View-Funktionen von Ihrem eigenen Knoten ausgeführt werden, während das Ausführen einer normalen Funktion, die in den Speicher schreibt, einen Miner erfordert, um diese Funktion auszuführen und Gas zu verbrauchen.