Utilice siempre "memoria" para las variables creadas dentro de las funciones. ¿Mala práctica?

¿Es una mala práctica usar sistemáticamente la memorypalabra clave para las variables declaradas dentro de una función (que no sea constructora)?

Respuestas (1)

Es una buena práctica usar explícitamente memoryo storageaclarar si una variable contiene un puntero a la memoria o al almacenamiento.

No siempre debe usar la memorypalabra clave, porque podría hacer que su código sea realmente ineficiente: cuando asigna una matriz desde el almacenamiento a una memoryvariable de puntero, la matriz completa se leerá desde el almacenamiento y se copiará en la memoria.

Aquí hay un ejemplo de una situación en la que no debe usar memory:

contract Test
{
    uint256[1000] lotsOfNumbersInStorage;
    uint256[1000] moreNumbersInStorage;
    function calculateSomething(uint256 a) public view returns(uint256)
    {
        uint256[1000] memory theChosenArray;
        if (a > 0) theChosenArray = lotsOfNumbersInStorage;
        else theChosenArray = moreNumbersInStorage;
        return theChosenArray[3] * theChosenArray[a];
    }
}

Esas asignaciones theChosenArrayparecen inocentes, pero copiarán toda la matriz del almacenamiento a la memoria, lo que costará al menos 200 000 gas (200 gas por lectura de almacenamiento * 1000 elementos). En este caso, debe declarar theChosenArraycomo un storagepuntero, no como un memorypuntero.

Escriba su fragmento de código: las 2 matrices que declaró inicialmente están almacenadas de manera predeterminada, ya que son matrices, ¿no es así?
@hartmut Están en almacenamiento porque han sido declarados dentro del contrato y no dentro de una función
Gracias por esta precisión. ¿Hay alguna variable declarada dentro de un contrato, en lugar de dentro de una función, POR DEFECTO, en el almacenamiento?
@hartmut Sí, eso es correcto