¿Por qué las variables locales se asignan al almacenamiento en lugar de a la memoria?

Las variables locales (es decir, las variables declaradas dentro de las funciones) se mantienen en el almacenamiento persistente de forma predeterminada en lugar de la memoria no persistente ( fuente ).

El valor de una variable local no puede persistir entre invocaciones de funciones, por lo que, en mi opinión, tiene más sentido tener variables locales almacenadas en la memoria durante la ejecución de una llamada de función. ¿Alguien podría explicar el propósito de esta decisión?

Información adicional: esto solo se aplica a tipos de datos complejos (matrices y estructuras). Todos los demás tipos locales están predeterminados en la memoria. Aparte de eso, ¡buena pregunta!
Esta es una excelente pregunta. Te contestaría si pudiera, pero no puedo.

Respuestas (2)

Parece estar relacionado con el tipo de datos que está utilizando. Como señaló TripleSpeeder, solo los tipos de datos complejos (matrices y estructuras) tienen funciones de almacenamiento interno predeterminadas, mientras que todos los demás están predeterminados en la memoria.

Dentro de esta pregunta de StackExchange hay una descripción de la diferencia entre memoria y almacenamiento. Parafraseando una de las respuestas:

El almacenamiento es un almacén de clave/valor donde las claves y los valores son ambos de 32 bytes. La memoria es una matriz de bytes. La memoria comienza con tamaño cero, pero se puede expandir en fragmentos de 32 bytes simplemente accediendo o almacenando memoria en índices mayores que su tamaño actual.

Una consecuencia de esta diferencia de diseño es que el almacenamiento es dinámico y la memoria no. Debido a que las matrices y las estructuras son complejas y pueden tener una longitud variable, están predeterminadas para el almacenamiento, que tiene este comportamiento clave:valor. Las variables más simples como bool, uint, etcétera no tienen una longitud variable y, por lo tanto, están predeterminadas en la memoria, que es más económica que el almacenamiento . Entonces, piense en la elección del diseño como un compromiso entre flexibilidad y costo.

Es posible crear matrices de memoria , pero una vez creadas, no se pueden cambiar de tamaño (consulte la sección Asignación de matrices de memoria).

Me tomó un tiempo, pero tuve un malentendido fundamental cuando hice esta pregunta. Las variables locales complejas no se "mantienen almacenadas" en absoluto, siempre son una referencia a alguna variable de estado. Este es el caso en el siguiente ejemplo de una variable local compleja:

contract Thingy {
    uint256[] stateArray;
    function doStuff() public {

        // By default solidity will create the below as a `storage reference`
        // This is the same as declaring as:
        // uint256[] storage localReference = stateArray;
        // This is essentially a pointer to the state variable's storage location

        uint256[] localReference = stateArray;

        // If it is required that the array only exists locally,
        // one must explicitly state that the variable is to be
        // held in memory

        uint256[] memory memArray = new uint256[](5);
    }
}

Debido a la diferencia en la implementación de storagey memory, las variables complejas locales (declaradas memory) deben tener un tamaño fijo en tiempo de compilación. Las variables de almacenamiento pueden tener un tamaño dinámico.