17

Non-constant functions are limited in computational complexity by the block gas limit. I assume, but am not sure, that this does not apply to view/pure functions. Are view/pure functions in any way limited in computational complexity other than the fact that I'd have to wait for quite a while until e.g. a long loop is executed?

1
  • 2
    The constant keyword isn't actually a part of the protocol specification, so its behavior in edge cases is largely up to the client. The only relevant specification is the JSON-RPC method eth_call . In practice, most clients respect the gas limit for the block that they are simulating the transaction in, but you shouldn't rely on that being the case across all clients. Nov 5, 2016 at 17:18

2 Answers 2

15

view/pure functions are limited by the gas provided to it. They still "use" gas, even though the sender (from account) doesn't get "charged" for the gas.

view, pure are Solidity keywords but currently only an indicator for Javascript web3.js to use JSON-RPC eth_call instead of 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 and sendTransaction are very similar (under the hood), with the main difference being the former is a simulation. But the simulation still "uses" gas, and understandably can cause confusion. To perform a complex computation in a view/pure function, you may need to explicitly specify plenty of gas like: myContractInstance.myMethod.call(param1, {gas:990000000})

For example, Geth "only" provides 50 million gas:

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

As @Tjaden commented, there are basically no specs about eth_call, so other clients and browser-solidity may behave differently from Geth.

4
  • Thanks, one thing I'd add in case people get overboard when specifying the gas is to put the gas value in quotes if it exceeds the largest number that Javascript allows.
    – eth
    Dec 24, 2016 at 6:31
  • What would the gas limit be when using MetaMask? Do they use Geth? Dec 27, 2017 at 23:25
  • @EliezerSteinbock I think 2 things: asking separation quesiton is better, and MetaMask won't pop up with eth_call.
    – eth
    Dec 30, 2017 at 14:26
  • 1
    The 50M gas logic stills seems to be the case in 2022: github.com/ethereum/go-ethereum/blob/…
    – eth
    Jan 16, 2022 at 23:37
5

The computational work needed by a constant or non-constant function is the same when you create your contract or if you execute the function. The initial cost depends on the operations executed in the EVM, each opcode has its own price. You could check the list here (maybe outdated).

However, the "constant" keyword indicates that the function is not supposed to modify the states, and no gas will be used because it allows the function to be executed locally/off blockchain in your node.

Test:

enter image description here

enter image description here

Edit: let's try to execute a loop within a constant function to get an idea of the computational work:

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;
 }
}

If we run this constant function with the input 1001, we get the result 0X

enter image description here

If we run the same function without the constant type and with the same input, we get an error: Gas required exceeds limit

enter image description here

So even if we are using a constant function, we are still under gasLimit limitation. Think of it as if you are using the constant function you are just paying yourself within a gasLimit.

5
  • It makes sense to me that the computational effort to me is the same, but I do not see this answering my question if there are limitations to the computational complexity of constant functions.
    – SCBuergel
    Nov 5, 2016 at 13:14
  • check the edit in the answer
    – Badr Bellaj
    Nov 5, 2016 at 15:37
  • Ok, so even constant functions seem to be subject to the default gas limit and probably also to the block gas limit, I just confirmed in Ethereum Studio. This does not make sense to me, see also: github.com/ethereum/go-ethereum/issues/3237
    – SCBuergel
    Nov 5, 2016 at 18:15
  • @Sebastian: Yes they're subject to the gas provided and since you're using Geth, I think you only get 50M gas for eth_call so try specifying more.
    – eth
    Nov 7, 2016 at 12:35
  • The answer is a little messy because the loop modifies state and should not be declared constant/view. Declaring j inside the function should allow for arbitrarily large gas specifications. To clarify, Remix enforces view won't modify state, but solc compiler doesn't yet, so this would not work with testing on your station. Nov 28, 2018 at 19:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.