Непостоянные функции ограничены по вычислительной сложности пределом блочного газа. Я предполагаю, но не уверен, что это не относится к функциям view
/ pure
. Являются ли view
/ pure
функции каким-либо образом ограниченными в вычислительной сложности, кроме того факта, что мне придется довольно долго ждать, пока, например, не будет выполнен длинный цикл?
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.
Вычислительная работа, необходимая для функции 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
.j
внутри функции должно допускать сколь угодно большие спецификации газа. Чтобы уточнить, Remix принуждает представление не изменять состояние, но компилятор solc еще не делает этого, поэтому это не будет работать при тестировании на вашей станции.
Тьяден Хесс
constant
слово на самом деле не является частью спецификации протокола, поэтому его поведение в крайних случаях во многом зависит от клиента. Единственная соответствующая спецификация — это метод JSON-RPCeth_call
. На практике большинство клиентов соблюдают лимит газа для блока, в котором они имитируют транзакцию, но вы не должны полагаться на то, что это относится ко всем клиентам.