Tengo una construcción como esta:
var s = SomeStruct(a, b);
map1[addr1] = s;
map2[addr2] = s;
... y quiere que ambos mapas apunten a los mismos datos.
Ahora si después hago
map1[addr1].field1 = x;
... luego map2[addr2].field1
aún devuelve el valor inicial en lugar de x, lo que sugiere que se crearon 2 copias de los datos cuando se asignaron inicialmente a los mapas.
Pregunta: ¿Cómo puedo evitar esta duplicación?
No hay una manera simple de hacer esto directamente. De los documentos de solidez :
El mapeo o el arreglo dinámico en sí ocupa un espacio (vacío) en el almacenamiento en alguna posición p de acuerdo con la regla anterior (o al aplicar recursivamente esta regla para mapeos a mapeos o arreglos de arreglos). Para una matriz dinámica, esta ranura almacena la cantidad de elementos en la matriz (las matrices de bytes y las cadenas son una excepción aquí, consulte a continuación). Para una asignación, la ranura no se usa (pero es necesaria para que dos asignaciones iguales una después de la otra usen una distribución de hash diferente). Los datos de la matriz se encuentran en keccak256(p) y el valor correspondiente a una clave de mapeo k se encuentra en keccak256(k . p) donde . es concatenación. Si el valor es nuevamente un tipo no elemental, las posiciones se encuentran agregando un desplazamiento de keccak256(k . p).
Es decir, las asignaciones no contienen punteros a valores. Las asignaciones son formas de convertir claves arbitrarias en punteros a valores. Sería astronómicamente improbable que dos claves de mapeo diferentes apunten a la misma ubicación en la memoria y, por lo tanto, compartan un valor.
Pero hay una solución.
Let map1
y map2
be asignaciones de direcciones a uints. Luego, use una matriz dinámica de someStructs o una asignación de uints a someStructs. Almacene las estructuras reales en esta última matriz o asignación. Usa los uints de map1
y map2
como una especie de puntero casero a dichas estructuras. Esto no debería usar mucho más gas al final.
didi_X8
Mateo Schmidt
GGizmos