Necesitaba una forma de borrar una matriz de almacenamiento en mi contrato. He visto esta respuesta, pero traté de pensar en un enfoque diferente (lo más probable es que mis matrices contengan una enorme cantidad de elementos) y he llegado a esto.
Creo una matriz de almacenamiento vacía del mismo tipo que la matriz que quiero borrar. Luego solo asigno una matriz vacía a una matriz llena. Aquí está el contrato que usé para las pruebas.
pragma solidity ^0.4.18;
contract Test {
address[] array;
address[] helper;
function Test() public {
array.push(0x0);
array.push(0x0);
array.push(0x0);
array.push(0x0);
}
function getSize() public view returns (uint256) {
return array.length;
}
function clear() public {
array = helper;
}
}
Funciona según lo previsto, getSize()
devuelve 0 después de llamar clear()
.
Así que ahora me pregunto si hay algunos problemas ocultos en este enfoque, incluyendo algo como "punteros colgantes" o aumento en el costo de la gasolina.
Gracias de antemano.
Después de leer documentos sobre tipos a fondo, descubrí que llamar delete
a una matriz dinámica libera toda la memoria asignada.
delete a
asigna el valor inicial para el tipo aa
. Es decir, para números enteros es equivalente aa = 0
, pero también se puede usar en arreglos, donde asigna un arreglo dinámico de longitud cero o un arreglo estático de la misma longitud con todos los elementos reiniciados.
Internamente, llamar delete
a la matriz lo asigna a una nueva matriz vacía, como hice yo.
Es importante notar que
delete a
realmente se comporta como una asignación aa
, es decir, almacena un nuevo objeto ena
.
El costo de transacción es menor para la delete
llamada que para la asignación manual a una matriz vacía (sin hablar de almacenar esta matriz vacía en la memoria de almacenamiento). En mi ejemplo, eliminar una matriz de 1000 direcciones llamando delete
cuesta 5060808 gas; eliminar la misma matriz por asignación manual cuesta 5270025 gas.