Ethereum Solidity: memoria vs almacenamiento y cómo inicializar una matriz dentro de una estructura

En el Telegrama de Loom Network (¡que tiene ~ 8,000 miembros!), Las personas hacen preguntas sobre varios temas, como la hoja de ruta de Loom, las preguntas teóricas de blockchain y Ethereum, y la solución de problemas de Solidez.

Se hizo una pregunta específica, que implicaba inicializar una matriz dentro de una estructura. La persona que lo solicitó proporcionó su código, preguntándose por qué no funciona. No podía pensar en una respuesta en la parte superior de mi cabeza, así que decidí hablar brevemente sobre este tema en una publicación.

El código que no funciona se puede encontrar a continuación. Te animo a que intentes encontrar una solución por ti mismo (has estado practicando en CryptoZombies todo este tiempo, ¿no?).

Sigue leyendo para encontrar la respuesta.

Cabe señalar que en el violín anterior, la memoria de palabras clave es necesaria al declarar la sala de variables. Si se declarara como Room room, el compilador devolvería el siguiente error:

TypeError: Tipo struct StructArrayInitWrong.Room La memoria no es implícitamente convertible al tipo esperado struct StructArrayInitWrong.Room puntero de almacenamiento.

Alguna teoría

Las variables de almacenamiento de un contrato son las que definen el estado de su contrato y solo se cambian mediante las llamadas de sendTransaction [1].

Las variables de memoria son variables temporales que existen solo dentro de la función de llamada (no se pueden declarar fuera de una). Se borran después de que la función sale y, en general, son más baratos de usar que las variables de almacenamiento: más detalles sobre los costos de gas aquí.

Veamos un ejemplo para comprender cómo se puede usar una variable de almacenamiento en una función para afectar el estado de un contrato.

En el violín a continuación, se pasa una copia de x en g () como y, por lo tanto, la variable de estado x no se modificará después de la ejecución (es por eso que usamos la palabra clave pura.

Por otro lado, y en h () se declara como almacenamiento, lo que significa que x se pasa por referencia. Como resultado, la variable de estado x se modifica después de la llamada a h ().

Puede probar el resultado llamando a f () y luego inspeccionando el valor de y [2]. Aunque se llama a g () después de h (), no modifica el valor de la variable de estado.

Basta de teorizar, vamos a la respuesta a la pregunta inicial.

Como no podemos inicializar la matriz de jugadores al inicializar la estructura, nos vemos obligados a hacerlo en pasos:

  1. Inicialice la estructura de la sala a los valores predeterminados con una matriz de jugadores vacía, como se describe aquí y en este violín.
  2. Empuje la habitación a la matriz de habitaciones.
  3. Empuje msg.sender a la matriz de jugadores de la última sala (rooms.length-1 siempre se refiere al último elemento de una matriz).

Código de trabajo Fiddle a continuación:

El truco aquí es que la nueva dirección [] (0) asigna memoria para una matriz vacía de direcciones. Después de la inicialización, la sala se agrega a las salas y ahora forma parte de una variable de almacenamiento. Esto nos permite operar en los reproductores de matriz y empujarle valores.

Nota: Si hiciéramos un nuevo uint [] (8) obtendríamos una matriz de 8 ceros. Puedes probarlo en este violín.

Eso es todo por hoy, espero que hayamos aclarado algunos malentendidos con respecto al almacenamiento / memoria y cómo usarlos en sus funciones. Háganos saber sus preguntas en nuestro canal de Telegram, y si no se pueden responder en unos pocos mensajes, le dedicaremos una publicación (¡o tal vez una lección de CryptoZombies!)

Loom Network es la plataforma de blockchain elegida por desarrolladores dapp serios: Universal Layer 2 que brinda a los desarrolladores las herramientas que necesitan para construir dapps funcionales orientados al usuario hoy en día.

¿Nuevo en Loom? Empieza aqui.

¿Quiere apostar sus tokens LOOM y ayudar a asegurar Loom Network? Averiguar como.

Y si te ha gustado este artículo y quieres mantenerte al día, inscríbete en nuestra lista de correo privada.