Могут ли функции Solidity view/pure быть произвольно сложными?

Непостоянные функции ограничены по вычислительной сложности пределом блочного газа. Я предполагаю, но не уверен, что это не относится к функциям view/ pure. Являются ли view/ pureфункции каким-либо образом ограниченными в вычислительной сложности, кроме того факта, что мне придется довольно долго ждать, пока, например, не будет выполнен длинный цикл?

Ключевое constantслово на самом деле не является частью спецификации протокола, поэтому его поведение в крайних случаях во многом зависит от клиента. Единственная соответствующая спецификация — это метод JSON-RPCeth_call . На практике большинство клиентов соблюдают лимит газа для блока, в котором они имитируют транзакцию, но вы не должны полагаться на то, что это относится ко всем клиентам.

Ответы (2)

view/ pureфункции ограничены предоставленным ему газом . Они по-прежнему «используют» газ, даже если отправитель ( fromаккаунт) не получает «плату» за газ.

view, pureявляются ключевыми словами Solidity, но в настоящее время являются лишь индикатором использования Javascript web3.js JSON-RPC eth_callвместо 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 и sendTransaction очень похожи (внутри), с основным отличием в том, что первый является симуляцией. Но симуляция по-прежнему «использует» газ и по понятным причинам может вызвать путаницу. Чтобы выполнить сложные вычисления в функции view/ pure, вам может потребоваться явно указать большое количество газа, например:myContractInstance.myMethod.call(param1, {gas:990000000})

Например, Гет «всего» дает 50 миллионов газа:

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

Как прокомментировал @Tjaden, в eth_call практически нет спецификаций, поэтому другие клиенты и надежность браузера могут вести себя иначе, чем Geth.

Спасибо, я бы добавил одну вещь на случай, если люди переусердствуют при указании газа, — это указать значение газа в кавычках, если оно превышает максимальное число, разрешенное Javascript .
Каким будет лимит газа при использовании MetaMask? Они используют Geth?
@EliezerSteinbock Я думаю о двух вещах: лучше задать вопрос о разделении, и MetaMask не будет появляться с eth_call.
В 2022 году 50-миллионная газовая логика все еще актуальна: github.com/ethereum/go-ethereum/blob/…

Вычислительная работа, необходимая для функции constantили non-constant, одинакова при создании контракта или при выполнении функции. Начальная стоимость зависит от операций, выполняемых в EVM, у каждого опкода своя цена. Вы можете проверить список здесь (возможно, устаревший).

Однако ключевое слово «константа» указывает, что функция не должна изменять состояния, и газ не будет использоваться, поскольку он позволяет выполнять функцию locally/off blockchainна вашем узле.

Тест :

введите описание изображения здесь

введите описание изображения здесь

Редактировать : давайте попробуем выполнить цикл внутри постоянной функции, чтобы получить представление о вычислительной работе:

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

Если мы запустим эту константную функцию со входом 1001, мы получим результат 0X

введите описание изображения здесь

Если мы запустим ту же функцию без константного типа и с теми же входными данными, мы получим ошибку:Gas required exceeds limit

введите описание изображения здесь

Таким образом, даже если мы используем константную функцию, мы все еще находимся под ограничением gasLimit. Думайте об этом, как если бы вы использовали постоянную функцию, которую вы просто платите себе в пределах gasLimit.

Для меня имеет смысл, что вычислительные усилия для меня одинаковы, но я не вижу в этом ответа на мой вопрос, существуют ли ограничения на вычислительную сложность функций constant.
проверьте правку в ответе
Итак, похоже, что даже постоянные функции подчиняются лимиту газа по умолчанию и, возможно, также лимиту газа блока, как я только что подтвердил в Ethereum Studio. Для меня это не имеет смысла, см. также: github.com/ethereum/go-ethereum/issues/3237
@Sebastian: Да, на них распространяется предоставленный газ, и, поскольку вы используете Geth, я думаю, вы получаете только 50 миллионов газа для eth_call, поэтому попробуйте указать больше.
Ответ немного запутан, потому что цикл изменяет состояние и не должен быть объявлен константой/представлением. Объявление jвнутри функции должно допускать сколь угодно большие спецификации газа. Чтобы уточнить, Remix принуждает представление не изменять состояние, но компилятор solc еще не делает этого, поэтому это не будет работать при тестировании на вашей станции.