Obtención de un error al intentar almacenar grandes cargas útiles (13-20kB)

Creé un contrato inteligente simple para almacenar grandes cantidades de datos (13-20kB) en la cadena de bloques de Ethereum. Pero cuando trato de realizar una transacción, a veces fallan (con poca correlación con la cantidad de datos) con un mensaje de "¡Advertencia! Error encontrado durante la ejecución del contrato [Fuera de gasolina] "

El límite de gas es 3000000 y no hay un umbral de datos claro que haga que la transacción falle. Dos transacciones con el mismo contenido pueden comportarse de manera diferente (una da un error y la otra no).

Aquí está el código que estoy usando para almacenar los datos:

contract SimpleStorage { 
    mapping(address => string) public Usersdata; 
    function Storedata(string data) public { 
        Usersdata[msg.sender] = data; 
    } 

    function getData() public view returns (string) { 
        return Usersdata[msg.sender]; 
    } 
}
En primer lugar, ¡espero que no vayas a ejecutar esto en la red principal! En segundo lugar, 3 millones de gasolina no son suficientes para almacenar tantos datos. ¿Cómo estás almacenando los datos? ¿Lo estás incluyendo como datos tx?
Se ejecuta en la red de prueba en este momento, pero planeo ejecutarlo en la red principal en el futuro.
¿Cómo estás almacenando los datos en la cadena? ¿Simplemente lo incluye como datos tx o lo coloca en almacenamiento por contrato?
Cuando las transacciones son exitosas, usan considerablemente menos gas. Y sí, los datos se almacenan como datos tx.
Realmente no puedo responder ninguna pregunta sin ver el contrato con el que estás interactuando.
contract SimpleStorage { mapeo (dirección => cadena) datos de usuarios públicos; function Storedata (cadena de datos) public { Usersdata [msg.sender] = data; } function getData() vista pública devuelve (cadena) { return Usersdata[msg.sender]; } }

Respuestas (1)

Según el contrato que comentó (y edité para agregar a la pregunta original), no es sorprendente que tenga problemas con el gas. El almacenamiento por contrato cuesta 20k para la inicialización de una ranura, y cada ranura almacena 32 bytes. Almacenar 10 KB de datos en almacenamiento costaría aproximadamente 10000/32*20000 gas, que es más de 6 millones de gas. Esto también ignora el costo de los datos como datos de entrada, que no es barato (aunque es mucho más barato que los costos de almacenamiento). En general, almacenar grandes conjuntos de datos como este en la cadena se considera una mala práctica.

Hice una transacción con una carga útil de 10kB y usó ~7000000 de gas. Establecí el precio del gas en 1 gwei. Que solo cuesta $0.78. ¿El precio será el mismo si lo implemento en la red principal? ¿Conoce alguna opción razonable para el almacenamiento en cadena?
No existe una forma económica de almacenar tantos datos en la cadena. No es realista querer agregar tantos datos al almacenamiento. Si no necesita operar con los datos dentro de su contrato y es solo para almacenamiento, entonces puede almacenar los datos en IPFS y poner el hash de IPFS en la cadena.
@flygoing, diga si "Usersdata" ya tiene 1000 entradas; EVM tiene que leer todos los datos en la memoria; agregue una nueva entrada y persista una nueva versión. En ese caso; ¿El costo incluye solo el tamaño de la nueva entrada o también el tamaño de las entradas existentes?
Asegúrese de no confundir la memoria y el almacenamiento, son dos cosas muy diferentes. El EVM no tiene que leer todos los datos. En el contrato que usaste como ejemplo, solo tendrías que pagar el precio de almacenar los nuevos datos, nada más, pero por supuesto eso es extremadamente costoso.