¿Cuál es la diferencia entre memoria y almacenamiento?
Tanto desde el punto de vista de EVM como del diseño del contrato.
¡Gracias!
Son análogos a la memoria y al almacenamiento en el disco duro de una computadora. El contrato puede usar cualquier cantidad de memoria (siempre que pueda pagarla, por supuesto) durante la ejecución de su código, pero cuando la ejecución se detiene, todo el contenido de la memoria se borra y la siguiente ejecución comenzará de nuevo. El almacenamiento, por otro lado, persiste en la propia cadena de bloques, por lo que la próxima vez que el contrato ejecute algún código, tendrá acceso a todos los datos que almacenó previamente en su área de almacenamiento.
La memoria es temporal. El almacenamiento es permanente. Por ejemplo, realizaría cálculos intermedios utilizando la memoria y luego guardaría el resultado en el almacenamiento .
El almacenamiento es un almacén de clave/valor donde las claves y los valores son ambos de 32 bytes. Es escaso (como una tabla hash) y no hay ahorros de gas inherentes al tener dos valores de 32 bytes uno al lado del otro. Almacenar uno de los valores en la tecla 1 y el otro en la tecla 1000 cuesta la misma cantidad de gas que almacenarlos en la tecla 1 y la tecla 2. (Aún es posible ahorrar gas al empaquetar el almacenamiento, como ajustar 2 uint128
valores dentro de una sola tecla , en lugar de usar 2 teclas).
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. Dado que la memoria es contigua , ahorra gas para mantenerla empaquetada y reducir su tamaño, en lugar de tener grandes parches de ceros. Es más barato tener una matriz de longitud 2 que almacene 2 valores, que una matriz de longitud 1000 donde los valores están en los extremos de la matriz y el medio son todos ceros.
La wiki de sutilezas explica con más detalle los costos de gasolina para usar la memoria:
La tarifa por expandir la memoria se determina a través de un método de resta de integrales. Específicamente, TOTALFEE(SZ) = SZ * 3 + floor(SZ**2 / 512)
es la tarifa total para expandir la memoria a SZ
fragmentos de 32 bytes (nota: los fragmentos parcialmente llenos se cuentan, por lo que 33 bytes = 2 fragmentos), y si una operación en particular expande la memoria de tamaño x
a y
, el costo de gas adicional esTOTALFEE(y) - TOTALFEE(x)
Los costos de almacenamiento de gas son principalmente: 20,000 de gas cuando un valor se establece de cero a distinto de cero; 5.000 de gas al escribir en el almacenamiento existente o establecer un valor en cero; y un reembolso de gasolina de 15,000 cuando un valor distinto de cero se establece en cero.
EDITAR: EIP-2200 finalizado en 2018 tiene más explicaciones sobre los costos de almacenamiento, como 800 de gas para "almacenar" el mismo valor .
uint128[1] memory t; t[0] = 10;
en mi función, el costo del gas que lo llama es 21581. Cuando si elimino esas 2 líneas de la función (que estarán totalmente vacías), ahora es 21394. Hay como 187 de diferencia de gas. Acabo de usar 1-2 ranuras como máximo. Poniendo 2 en la fórmula, obtenemos 6. ¿Alguna idea?la memoria es como la memoria RAM de su código, que contiene los datos hasta la ejecución de su función, una vez que finaliza la ejecución de la función, se elimina. Por otro lado , el almacenamiento es como la base de datos que existe en la cadena de bloques independientemente de la ejecución de la función. .
dionisio