Gasfehler beim Lesen aus der Blockchain?

function getPosts(address[] subscriptions, uint[] subscriptionIndexes, uint count) public view returns 
            (address[], bytes32[], bytes32[], uint[]) {

            address[] storage postSenders;
            bytes32[] storage postLinks;
            bytes32[] storage postComments;
            uint[] storage postTimestamps;

            while(postSenders.length < count) {
                (uint postId, address subscription) = getNextPost(subscriptions, subscriptionIndexes);


                postSenders.push(subscription);
                postLinks.push(addressToLinks[subscription][postId]);
                postComments.push(addressToComments[subscription][postId]);
                postTimestamps.push(addressToTimestamps[subscription][postId]);
            }

            return (postSenders, postLinks, postComments, subscriptionIndexes);
        }

Das obige funktioniert gut, wenn ich ein Array der Länge 311 übergebe, gibt aber diesen Fehler zurück, wenn ich ein Array der Länge 312 oder größer übergebe:

Returned error: base fee exceeds gas limit at Object.ErrorResponse 

Ich wusste nicht, dass Gas im Spiel war, als ich nur aus der Blockchain gelesen habe?

Ich habe versucht, das Gaslimit wie folgt zu erhöhen (mit web3. v 1.0):

let results = await myContract.methods.getPosts(subscriptions, indexes, 3).call({gas: 1000000000});

Aber jetzt bekomme ich diesen Fehler jedes Mal, unabhängig davon, was ich für die Gasmenge eingegeben habe und unabhängig davon, wie groß das subscriptionsArray ist.

Irgendwelche Ideen, wie ich das effizienter machen kann oder warum es fehlschlägt?

Vielen Dank!

Antworten (1)

Mehrere Probleme.

Sie verwechseln das gasmit der Transaktion gelieferte mit dem gasLimit. Das gasLimitist eine Netzwerk-Eigenschaft. In einer privaten Kette oder einem Simulator können Sie das Limit festlegen, wo Sie möchten, aber in einem öffentlichen Netzwerk wird es von den Bergleuten gewählt und Sie können es nicht kontrollieren.

Dies gasist die Kraftstoffmenge, die zur Ausführung der Transaktion bereitgestellt wird. Da kein Block mehr Gas enthalten kann als der gasLimit, kann keine einzelne Transaktion den Block überschreiten gasLimit. Das Überschreiten dieser Grenze ist ein automatischer Fehler.

Die Funktion ist ineffizient konstruiert. Durch die Rückgabe all dieser unbegrenzten Arrays gibt es keine Obergrenze für die Gaskosten. In der Praxis ist dieses Muster unnötig. Es ist besser, Kunden das anfordern zu lassen, was sie benötigen, Element für Element. Auf diese Weise kann ein großer Aufwand, der das Budget überschreitet, in viele kleinere, einzeln im Budget liegende Bemühungen unterteilt werden.

Es stimmt zwar, dass Nur-Lese-Operationen zur "Rückgabe" des gelieferten Gases führen (tatsächlich gibt es nichts zu erinnern, da das Netz nicht informiert wird), aber die Gasabrechnung ist immer noch im Spiel, selbst wenn die Funktion nicht funktioniert wird mit "Trockenlauf" .call()-Methode aufgerufen. Es fällt sogar aus, wenn ihm das Benzin ausgeht.

Die Funktion selbst scheint den Speicher aktualisieren zu wollen, verwendet jedoch den viewModifikator. Das sieht verdächtig aus.

Die unbegrenzte whileSchleife scheint bis zu einem bestimmten Maßstab zu funktionieren, kostet aber mehr und versagt schließlich vollständig.

In Betracht ziehen,

function getAddressPost(address poster, uint row) public view returns(...

und geben Sie einen einzelnen Datensatz ohne dynamische Elemente zurück, sodass die Kosten in allen Maßstäben gleich sind.

Ich hoffe es hilft.