Können Solidity-Ansichten/reine Funktionen beliebig komplex sein?

Nicht konstante Funktionen sind in der Rechenkomplexität durch die Sperrgasgrenze begrenzt. Ich gehe davon aus, bin mir aber nicht sicher, dass dies nicht für view/ pure-Funktionen gilt. Sind view/ pure-Funktionen in irgendeiner Weise in der Rechenkomplexität begrenzt, außer dass ich eine ganze Weile warten müsste, bis zB eine lange Schleife ausgeführt wird?

Das constantSchlüsselwort ist eigentlich kein Teil der Protokollspezifikation, daher hängt sein Verhalten in Grenzfällen weitgehend vom Client ab. Die einzige relevante Spezifikation ist die JSON-RPC- Methode eth_call . In der Praxis respektieren die meisten Kunden das Gaslimit für den Block, in dem sie die Transaktion simulieren, aber Sie sollten sich nicht darauf verlassen, dass dies bei allen Kunden der Fall ist.

Antworten (2)

view/ pureFunktionen werden durch das ihm zugeführte Gas eingeschränkt . Sie "verbrauchen" immer noch Gas, obwohl der Absender ( fromKonto) nicht für das Gas "belastet" wird.

view, puresind Solidity-Schlüsselwörter, aber derzeit nur ein Indikator dafür, dass Javascripteth_call web3.js JSON-RPC anstelle von verwendet eth_sendTransaction.

https://github.com/ethereum/wiki/wiki/JavaScript-API#contract-methods

// Automatically determines the use of call or sendTransaction based on the method type (constant keyword exists or not?)
myContractInstance.myMethod(param1 [, param2, ...] [, transactionObject] [, defaultBlock] [, callback]);

// Explicitly calling this method
myContractInstance.myMethod.call(param1 [, param2, ...] [, transactionObject] [, defaultBlock] [, callback]);

// Explicitly sending a transaction to this method
myContractInstance.myMethod.sendTransaction(param1 [, param2, ...] [, transactionObject] [, callback]);

call und sendTransaction sind sehr ähnlich (unter der Haube), wobei der Hauptunterschied darin besteht, dass Ersteres eine Simulation ist. Aber die Simulation "verbraucht" immer noch Gas und kann verständlicherweise Verwirrung stiften. Um eine komplexe Berechnung in einer view/ -Funktion durchzuführen pure, müssen Sie möglicherweise explizit viel Gas angeben, z. B.:myContractInstance.myMethod.call(param1, {gas:990000000})

Zum Beispiel liefert Geth „nur“ 50 Millionen Gas:

if msg.gas == nil {
    msg.gas = big.NewInt(50000000)
}

Wie @Tjaden kommentierte, gibt es im Grunde keine Spezifikationen zu eth_call, sodass sich andere Clients und Browser-Solidity möglicherweise anders verhalten als Geth.

Danke, eine Sache, die ich hinzufügen würde, falls die Leute bei der Angabe des Gases über Bord gehen, ist, den Gaswert in Anführungszeichen zu setzen, wenn er die größte Zahl überschreitet, die Javascript zulässt .
Was wäre die Gasgrenze bei der Verwendung von MetaMask? Verwenden sie Geth?
@EliezerSteinbock Ich denke 2 Dinge: Es ist besser, eine Trennungsfrage zu stellen, und MetaMask wird nicht mit eth_call angezeigt.
Die 50-Millionen-Gas-Logik scheint im Jahr 2022 der Fall zu sein: github.com/ethereum/go-ethereum/blob/…

Die Rechenarbeit, die eine constantor- non-constantFunktion benötigt, ist die gleiche, wenn Sie Ihren Vertrag erstellen oder wenn Sie die Funktion ausführen. Die anfänglichen Kosten hängen von den in der EVM ausgeführten Operationen ab, jeder Opcode hat seinen eigenen Preis. Sie können die Liste hier überprüfen (möglicherweise veraltet).

Das Schlüsselwort "constant" gibt jedoch an, dass die Funktion die Zustände nicht ändern soll und kein Gas verwendet wird, da die Funktion dadurch locally/off blockchainin Ihrem Knoten ausgeführt werden kann.

Prüfung :

Geben Sie hier die Bildbeschreibung ein

Geben Sie hier die Bildbeschreibung ein

Bearbeiten : Versuchen wir, eine Schleife innerhalb einer konstanten Funktion auszuführen, um eine Vorstellung von der Rechenarbeit zu bekommen:

pragma solidity ^0.4.0;

contract test_compexity{
   

 function f(uint256 n) constant  returns (uint256)  {
    uint256 j=0;
     while(j<n){
         j=j+1;
     }
  
 return j;
 }
}

Wenn wir diese konstante Funktion mit der Eingabe 1001 ausführen, erhalten wir das Ergebnis 0X

Geben Sie hier die Bildbeschreibung ein

Wenn wir dieselbe Funktion ohne den konstanten Typ und mit derselben Eingabe ausführen, erhalten wir einen Fehler:Gas required exceeds limit

Geben Sie hier die Bildbeschreibung ein

Selbst wenn wir also eine konstante Funktion verwenden, unterliegen wir immer noch der gasLimit-Beschränkung. Stellen Sie es sich so vor, als ob Sie die konstante Funktion verwenden, die Sie gerade innerhalb eines gasLimits bezahlen.

Es macht für mich Sinn, dass der Rechenaufwand für mich gleich ist, aber ich sehe nicht, dass dies meine Frage beantwortet, ob es Einschränkungen bei der Rechenkomplexität von constantFunktionen gibt.
Überprüfen Sie die Bearbeitung in der Antwort
Ok, also scheinen auch konstante Funktionen dem Default-Gas-Limit und wahrscheinlich auch dem Block-Gas-Limit zu unterliegen, habe ich gerade in Ethereum Studio bestätigt. Das ergibt für mich keinen Sinn, siehe auch: github.com/ethereum/go-ethereum/issues/3237
@Sebastian: Ja, sie unterliegen dem bereitgestellten Gas, und da Sie Geth verwenden, erhalten Sie meiner Meinung nach nur 50 Millionen Gas für eth_call, also versuchen Sie, mehr anzugeben.
Die Antwort ist ein wenig chaotisch, da die Schleife den Zustand ändert und nicht als Konstante/Ansicht deklariert werden sollte. Die Deklaration jinnerhalb der Funktion sollte beliebig große Gasspezifikationen ermöglichen. Zur Verdeutlichung: Remix erzwingt, dass die Ansicht den Status nicht ändert, der Solc-Compiler jedoch noch nicht, sodass dies beim Testen auf Ihrer Station nicht funktionieren würde.