Bucle con uso óptimo de gas

Actualmente tengo el siguiente bucle (algunas cosas quedan fuera)

mapping (address => uint) pendingWithdrawals;

function example () private{
    address[] tempList = List;
    for(uint k = 0; k < tempList.length; k++){
            Struct storage val = mapping[tempList[k]];
            pendingWithdrawals[tempList[k]] = (val.value);
    }
}

En esta situación, estoy recorriendo una lista que creé localmente para ahorrar gasolina y llamando a la asignación de retiros pendientes dentro del ciclo. Pero, ¿cómo puedo lograr el mismo objetivo con el mapeo? Como no puede asignar asignaciones, no puedo crear una asignación local, escribir en la asignación local y actualizar la nueva asignación global una vez que haya terminado. Lo que hace que este ciclo for sea muy costoso en términos de tener que llamar al almacenamiento en cada iteración dentro del ciclo.

¿Podría proporcionar un fragmento de código que funcione para que podamos ayudarlo más? ¿Qué es esta variable 'Lista', se pasa como parámetro o es una variable de almacenamiento de contrato? Y la línea "Struct storage val = mapping[tempList[k]];" no deja claro cuál es tu caso exacto.

Respuestas (1)

En mi opinión, incluso si pudiera crear un mapeo local, ponerle 10 valores y luego actualizar la variable de estado una vez, tendría que pagar por 10 ranuras de almacenamiento, porque el mapeo contiene 10 valores.

¿Hay alguna manera de reducir el costo de este método? ¿O es esto solo lo que está disponible en este punto en el lenguaje de solidez?
Tal vez haya una manera de empaquetar los enteros en uint128 de alguna manera.
Lo siento, quise decir usar uint128 en lugar de uint y empaquetarlos en una sola ranura de almacenamiento.
Sin embargo, no creo que eso funcione con asignaciones. La ranura en el almacenamiento de un valor de asignación es en realidad keccak256(k . p), donde k es la clave y p es el índice de ranura de la raíz de la asignación. Esto dificultaría mucho la compactación de varios valores en una sola ranura dado que tendrían claves separadas y, por lo tanto, diferentes ubicaciones en el almacenamiento.
Si esperaba muchas escrituras, entonces se podrían hacer ahorros al tener los valores almacenados en una matriz y hacer que el mapeo clave->valor apunte al índice en la matriz de la clave. Los elementos de la matriz pueden convertirse en uint128 o uint64 y empaquetarse en ranuras. Obviamente, esto es más costoso inicialmente, pero si se esperan muchas escrituras, entonces puede ser un gran ahorro de gasolina.
Estoy de acuerdo que es difícil. La única forma en que puedo pensar es si las entradas se agregan y recuperan siempre en pares, es decir, 2 claves y 2 valores al insertar, 2 claves al recuperar, que rara vez se puede usar.
Tu solución también es interesante.