Las funciones no constantes están limitadas en complejidad computacional por el límite de gas del bloque. Supongo, pero no estoy seguro, que esto no se aplica a view
/ pure
funciones. ¿Están view
/ pure
las funciones de alguna manera limitadas en complejidad computacional aparte del hecho de que tendría que esperar bastante tiempo hasta que, por ejemplo, se ejecute un ciclo largo?
view
/ pure
las funciones están limitadas por el gas que se le proporciona . Todavía "usan" gasolina, aunque al remitente ( from
cuenta) no se le "cobra" por la gasolina.
view
, pure
son palabras clave de Solidity, pero actualmente solo son un indicador para que Javascript web3.js use JSON-RPC eth_call
en lugar de eth_sendTransaction
.
https://github.com/ethereum/wiki/wiki/JavaScript-API#métodos-de-contrato
// 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 y sendTransaction son muy similares (bajo el capó), con la principal diferencia de que el primero es una simulación. Pero la simulación todavía "usa" gas y, comprensiblemente, puede causar confusión. Para realizar un cálculo complejo en una función view
/ pure
, es posible que deba especificar explícitamente mucho gas como:myContractInstance.myMethod.call(param1, {gas:990000000})
Por ejemplo, Geth "solo" proporciona 50 millones de gas:
if msg.gas == nil {
msg.gas = big.NewInt(50000000)
}
Como comentó @Tjaden, básicamente no hay especificaciones sobre eth_call, por lo que otros clientes y la solidez del navegador pueden comportarse de manera diferente a Geth.
El trabajo computacional que necesita una función constant
o non-constant
es el mismo cuando crea su contrato o si ejecuta la función. El costo inicial depende de las operaciones ejecutadas en la EVM, cada opcode tiene su propio precio. Puede consultar la lista aquí (tal vez desactualizada).
Sin embargo, la palabra clave "constante" indica que no se supone que la función modifique los estados, y no se usará gas porque permite que la función se ejecute locally/off blockchain
en su nodo.
Prueba :
Editar : intentemos ejecutar un ciclo dentro de una función constante para tener una idea del trabajo computacional:
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;
}
}
Si ejecutamos esta función constante con la entrada 1001, obtenemos el resultado 0X
Si ejecutamos la misma función sin el tipo constante y con la misma entrada, obtenemos un error:Gas required exceeds limit
Entonces, incluso si estamos usando una función constante, todavía estamos bajo la limitación de gasLimit. Piense en ello como si estuviera usando la función constante y solo se está pagando a sí mismo dentro de un gasLimit.
constant
funciones.j
dentro de la función debería permitir especificaciones de gas arbitrariamente grandes. Para aclarar, Remix exige que la vista no modifique el estado, pero el compilador solc aún no lo hace, por lo que esto no funcionaría con las pruebas en su estación.
tjaden hess
constant
palabra clave en realidad no forma parte de la especificación del protocolo, por lo que su comportamiento en casos extremos depende en gran medida del cliente. La única especificación relevante es el método JSON-RPCeth_call
. En la práctica, la mayoría de los clientes respetan el límite de gas para el bloque en el que están simulando la transacción, pero no debe confiar en que ese sea el caso para todos los clientes.