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 subscriptions
Array ist.
Irgendwelche Ideen, wie ich das effizienter machen kann oder warum es fehlschlägt?
Vielen Dank!
Mehrere Probleme.
Sie verwechseln das gas
mit der Transaktion gelieferte mit dem gasLimit
. Das gasLimit
ist 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 gas
ist 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 view
Modifikator. Das sieht verdächtig aus.
Die unbegrenzte while
Schleife 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.