¿Diferencia entre memoria y almacenamiento?

¿Cuál es la diferencia entre memoria y almacenamiento?

Tanto desde el punto de vista de EVM como del diseño del contrato.

¡Gracias!

Respuestas (3)

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 de la ejecución también se almacena "en la propia cadena de bloques", ya que forma parte de transacciones pasadas. Sin embargo, no es accesible para futuras ejecuciones del contrato directamente como lo es el 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 .

Detalles desde la perspectiva de EVM, su estructura y costos de gas.

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 uint128valores 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 SZfragmentos 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 xa 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 .

¿Puede explicar esta parte en detalle? 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.
@Rajat He realizado ediciones, pero no estoy seguro de cómo explicar más "escaso". ese es el problema o que buscas?
de hecho, si. La escasa es mi duda, pero después de dos meses y creando más contratos inteligentes que en ese momento, puedo entender tu respuesta (ahora) y agradecer el talento del que has explicado. Si es posible, ¿puede dirigirme a cualquier documentación desde donde pueda aprender las cosas que suceden en segundo plano? (¿Es el libro blanco o cualquier otra cosa?) ¡Esto me ayudará a apreciar mejor ethereum, y estaré en condiciones de responder como usted con toda la técnica en un lenguaje simple también!
En general, es uno más barato que el otro, si no es tan simple, ¿puede darnos una opinión sobre cómo decidir cuál usar?
@DanielKobe Sí, la memoria es más barata porque no es permanente. No quería repetir los puntos de Peter, pero puedo agregar una aclaración.
¿Mencionó los costos de almacenamiento pero no los costos de memoria?
@EralpB Está en el enlace wiki de sutilezas, pero lo he agregado para responder ahora también.
Creo que te referías a un reembolso de 20.000 de gasolina. Creo que esto tiene más sentido y también tenga en cuenta que establecer el valor en 0 cuesta 5000, lo que genera el reembolso de 15 000 que mencionó.
@NicSzer Puede parecer que los números se suman, pero creo que es más una coincidencia y no sigo tu comentario. Los números son del Libro Amarillo.
¿Por qué es "SUELO" y no "TECHO"?
@dionyziz Supongo que es piso porque es la división entera típica en la mayoría de los idiomas.
@eth Dado que menciona explícitamente que "se cuentan los fragmentos parcialmente llenos", parece que esto se contaría usando "CEIL" en lugar de "FLOOR" aquí. Un fragmento parcialmente lleno produciría un número no entero después de la división, y "CEIL" lo llevaría a que el fragmento parcialmente lleno se contara como un fragmento completamente lleno, que creo que es lo que hace el cálculo de la tarifa. ¿Sería esa la interpretación correcta?
@eth No estoy siguiendo la fórmula desafortunadamente. Si solo pongo 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?
@NikaKurashvili La parte que escribí sobre la memoria podría estar muy desactualizada. Le sugiero que publique una pregunta nueva y específica como ethereum.stackexchange.com/questions/91197/… (o ethereum.stackexchange.com/questions/90318/… ) y alguien puede ayudar. Entonces siéntase libre de publicar su propia respuesta aquí o editar para actualizar esta respuesta. (Ya edité esta respuesta a EIP-2200 ya que estaba usando un EIP anterior y es difícil hacer un seguimiento).

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. .

Esto no agrega nada a las respuestas existentes más detalladas.