Cuándo usar "Ver" y "Puro" en lugar de "Constante" [duplicado]

Según la solidez 0.4.17 Notas de la versión

esta versión finalmente verifica la vista de modificadores (solía llamarse constante) y funciones puras. Como regla general, use view si su función no modifica el almacenamiento y pure si ni siquiera lee ninguna información de estado, pero el compilador también sugerirá la restricción más estricta.

¿Qué significa eso en la práctica?

Respuestas (4)

En versiones anteriores, aplicábamos el constantmodificador para indicar que una función no cambia el estado de almacenamiento de ninguna manera. Por ejemplo:

pragma solidity 0.4.16; 

contract UseConstant {

    string greeting;

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

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

constantindica que la verificación de la red no será necesaria. Las personas que llaman reciben returnvalores (rápidamente, del almacenamiento y procesamiento local) en lugar de hash de transacciones.

Comenzando con solc 0.4.17, constantestá obsoleto a favor de dos modificadores nuevos y más específicos.

Ver Este es generalmente el reemplazo de constant. Indica que la función no alterará el estado de almacenamiento de ninguna manera.

Pure Esto es aún más restrictivo, lo que indica que ni siquiera leerá el estado de almacenamiento.

Una purefunción podría parecerse a este ejemplo muy artificial:

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

En Remix, recibirá una advertencia cuando use el constantmodificador anterior. Examinará el código de función e indicará la restricción máxima que puede aplicar de forma segura.

Espero eso ayude.

ACTUALIZAR

Esta es una pregunta y respuesta popular, así que decidí desarrollarla en una publicación mediana más detallada: https://blog.b9lab.com/calls-vs-transactions-in-ethereum-smart-contracts-62d6b17d0bc2

El constantmodificador tiene el significado de que la función no modificará el almacenamiento del contrato (pero la palabra constante en realidad no transmitió el significado para el que se usa).

Los nuevos reemplazos para constantdespués del lanzamiento de Solidity 0.4.17view y puretransmiten el significado de su uso.


viewse puede considerar como el subconjunto de los constantque leerán el almacenamiento (por lo tanto, la visualización). Sin embargo, el almacenamiento no se modificará.

Ejemplo:

contract viewExample {

    string state;

    // other contract functions

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

purese puede considerar como el subconjunto de constantdonde el valor de retorno solo será determinado por sus parámetros (valores de entrada). No habrá lectura ni escritura en el almacenamiento y solo se utilizarán variables locales (tiene el concepto de funciones puras en la programación funcional).

Ejemplo:

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;
    }

}

Para ejecutar/llamar estas pureo viewfunciones desde el exterior, no se necesita ninguna transacción. Solo un calles suficiente ya que el estado de la cadena de bloques no cambia al llamarlos. Por lo tanto, no se requiere gas/éter para usar estas funciones desde el exterior.

Sin embargo, las llamadas internas a estas funciones pueden costar gasolina si la llamada interna es de una transacción. Puede encontrar más detalles sobre cómo las llamadas internas a estos pueden costar gasolina aquí .

Digamos que tiene una función como esta en la biblioteca SafeMath:

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

Aquí no se lee ningún estado.

Mientras que

String something;

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

accedería al almacenamiento. Supongo que en el primer caso, al compilar el contrato, no es necesario implementar códigos de operación para leer el estado de ninguna manera, como sería el caso en el último ejemplo. Creo que esto debería ahorrar gasolina durante el despliegue.

Si una función en Solidity escribe en el almacenamiento, por ejemplo: sendTokenTo(John), no tendrá una de estas etiquetas. (esta función escribe en el almacenamiento porque debe cambiar el saldo de fichas de alguien en la cadena de bloques) Esto es a lo que está acostumbrado. En segundo lugar, si una función simplemente lee del almacenamiento, pero no escribe nada en el almacenamiento, por ejemplo: getTokenBalance(John), esta será una función de visualización . Por último, si una función no lee ni escribe almacenamiento, entonces es una función pura , por ejemplo: onePlusOne().

El uso de funciones puras y de vista permite que estas funciones consuman gas cero , porque no modifican el estado. Llamar a estas funciones con algo como web3.js dará como resultado que estas funciones puras/de vista sean ejecutadas por su propio nodo, mientras que ejecutar una función normal que escribe en el almacenamiento requerirá que un minero ejecute esta función, consumiendo gas.