Beim Versuch, große Payloads zu speichern, wird ein Fehler angezeigt (13-20 KB)

Ich habe einen einfachen Smart Contract erstellt, um große Datenmengen (13-20 kB) auf der Ethereum-Blockchain zu speichern. Aber wenn ich versuche, eine Transaktion durchzuführen, schlagen sie manchmal fehl (mit geringer Korrelation zur Datenmenge) mit der Fehlermeldung „Warnung! Fehler bei Vertragsausführung [Kein Gas]“.

Das Gaslimit beträgt 3000000 und es gibt keinen klaren Datenschwellenwert, der dazu führt, dass die Transaktion fehlschlägt. Zwei Transaktionen mit demselben Inhalt können sich unterschiedlich verhalten (eine gibt einen Fehler aus, die andere nicht).

Hier ist der Code, den ich verwende, um die Daten zu speichern:

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]; 
    } 
}
Zunächst einmal hoffe ich sehr, dass Sie dies nicht im Mainnet ausführen werden! Zweitens reichen 3 Millionen Gas nicht aus, um so viele Daten zu speichern. Wie speichern Sie die Daten? Fügen Sie es nur als TX-Daten hinzu?
Es läuft gerade im Testnetz, aber ich plane, es in Zukunft im Hauptnetz zu betreiben.
Wie speichern Sie die Daten in der Kette? Nimmst du es nur als tx-Daten auf oder legst du es in den Vertragsspeicher?
Wenn Transaktionen erfolgreich sind, verbrauchen sie erheblich weniger Gas. Und ja, die Daten werden als TX-Daten gespeichert.
Ich kann keine Fragen wirklich beantworten, ohne den Vertrag zu sehen, mit dem Sie interagieren.
Vertrag SimpleStorage { Zuordnung (Adresse => Zeichenfolge) öffentliche Benutzerdaten; function Storedata(string data) public { Usersdata[msg.sender] = data; } Funktion getData() öffentliche Ansicht gibt zurück (String) { return Usersdata[msg.sender]; } }

Antworten (1)

Basierend auf dem Vertrag, den Sie kommentiert haben (und ich habe ihn bearbeitet, um ihn der ursprünglichen Frage hinzuzufügen), ist es nicht verwunderlich, dass Sie auf Gasprobleme stoßen. Die Vertragsspeicherung kostet 20.000 für die Initialisierung eines Slots, und jeder Slot speichert 32 Bytes. Das Speichern von 10 KB Daten im Speicher würde etwa 10000/32*20000 Gas kosten, was über 6 Millionen Gas ist. Dies ignoriert auch die Kosten der Daten als Eingabedaten, die nicht billig sind (obwohl sie viel billiger sind als die Speicherkosten). Insgesamt gilt die Speicherung großer Datensätze wie dieser in der Kette als schlechte Praxis.

Ich habe eine Transaktion mit einer Nutzlast von 10 KB durchgeführt und sie hat ~ 7000000 Gas verbraucht. Ich habe den Gaspreis auf 1 Gwei festgelegt. Was nur 0,78 $ kostet. Wird der Preis derselbe sein, wenn ich ihn im Mainnet bereitstelle? Kennen Sie eine vernünftige Option zur On-Chain-Speicherung?
Es gibt keine billige Möglichkeit, so viele Daten in der Kette zu speichern. Es ist einfach unrealistisch, dem Speicher so viele Daten hinzufügen zu wollen. Wenn Sie die Daten im Rahmen Ihres Vertrags nicht verarbeiten müssen und diese nur zur Speicherung dienen, können Sie die Daten auf IPFS speichern und den IPFS-Hash in die Kette stellen.
@flygoing , sagen Sie, wenn "Usersdata" bereits 1000 Einträge hat; EVM muss alle Daten im Speicher lesen; neuen Eintrag hinzufügen und neue Version beibehalten. In diesem Fall; umfassen die Kosten nur die Größe des neuen Eintrags oder auch die Größe bestehender Einträge?
Stellen Sie sicher, dass Sie Arbeitsspeicher und Speicherplatz nicht verwechseln, das sind zwei sehr unterschiedliche Dinge. Die EVM muss nicht alle Daten lesen. In dem Vertrag, den Sie als Beispiel verwendet haben, müssten Sie nur den Preis für die Speicherung der neuen Daten bezahlen, sonst nichts, aber das ist natürlich extrem teuer.