Tengo una lista ordenada ordenada que contiene alrededor de 1000 elementos. Cuando recibo un artículo nuevo, mi objetivo es empujar el artículo a la lista manteniendo el orden ordenado. Entonces, si recibo un valor muy pequeño, debo iterar toda la lista para encontrar la cola de la lista.
El objetivo de la función constante es devolver la ubicación del índice para que se inserte la función de transacción.
La iteración (iterateListToFindPushIndex()) podría verse así:
struct Interval {
uint32 num; //contained value.
uint32 next; //points to next node on the linkedlist.
}
prevNode = self.list[self.head]; //head of the list, largest value.
currentNode = self.list[prevNode.next];
while( true ) {
if( s > currentNode.num ){
//self.list.push(Interval( { num: s, next: prevNode.next }) );
//prevNode.next = uint32(self.list.length - 1);
return prevNode.next;
//returned indexed would be use in transaction function to insert intem into the correct location.
}
prevNode = currentNode;
currentNode = self.list[currentNode.next];
}
Como sabemos cuando llamamos a una función constante, no cuesta nada y es de uso gratuito. Entonces, cuando encuentre la ubicación del índice a través de una función constante, no me costará gasolina.
function iterateListToFindPushIndex() constant returns(uint index){}
function func(intervalNode storage self) {
index = iterateListToFindPushIndex();
self.list.push(Interval( { num: s, next: index }) )
}
Dentro de una función de transacción, cuando itero a través de mi lista aunque no cambie ningún almacenamiento de memoria, me cuesta gasolina adicional.
Entonces, ¿es posible llamar a una función constante sin gastar gasolina dentro de una función de transacción?
Gracias por su valioso tiempo y ayuda.
Llamar a una constant
función dentro de una transacción cuesta tanto como llamar a una no constant
función dentro de una transacción. Lo constant
que significa es que, dado que no altera el estado, su nodo local puede ejecutarlo y decirle el resultado sin necesidad de una transacción. Esto no cuesta gasolina porque solo su nodo tiene que ejecutar el cálculo.
Puede usar esto para ahorrar combustible en una transacción ejecutando primero la función constante desde su código JavaScript para obtener un resultado y luego pasando ese resultado como un parámetro a la transacción. Sin embargo, a menos que su contrato confíe en la persona que lo envía, aún debe verificarlo dentro de la transacción. Esto aún puede ser útil: si tiene una lista ordenada y desea saber dónde colocar un elemento, puede ser útil verificarlo en el lado del cliente y encontrar el índice x
, pasar el índice x
como un parámetro de transacción, luego dejar el código de contrato inteligente en la transacción verifica que el artículo en x-1
viene antes de lo que está agregando y el artículo en x+1
viene después.
Una trampa es que los datos pueden cambiar entre leer un resultado y enviar una llamada que lo contenga a la cadena de bloques en una transacción, en cuyo caso su transacción fallará y tendrá que enviarla nuevamente.
Como sabemos cuando llamamos a una función constante, no cuesta nada y es de uso gratuito.
Esta afirmación es falsa. Me gustaría saber cuál es la fuente de esta declaración, ya que debería corregirse.
Una transacción, por definición, cambia el estado de la cadena de bloques de Ethereum, mueve ETH o bits.
Cuando las transacciones realizan cálculos, utilizan el tiempo de CPU de los mineros. No solo los mineros, sino también el tiempo de CPU de todos los nodos completos de Ethereum, ya que actualmente todas las transacciones se reproducen en todos los nodos. Los mineros no son sin fines de lucro y, naturalmente, le cobran por el servicio de usar su CPU. No importa si las subllamadas o los cómputos mutan el estado (no constante) o no tienen efectos secundarios (constante) si el resultado total de la transacción es el cambio de aunque sea un bit en la cadena de bloques de Ethereum.
Llamar a la función constante es gratis solo si consulta el estado desde su nodo local, ya que entonces no está haciendo una transacción, solo está haciendo una llamada de consulta RPC a su base de datos local de blockchain.
La función de llamada constant
podría aumentar su consumo de gas. El EVM ahora necesita buscar otra función y agregarla a la pila para calcular el valor correcto. Echa un vistazo al siguiente código, por ejemplo:
contract Child{
uint8 public age = 1;
function birthDay() { <-- gas used: 26933
age = age + 1;
}
function nextYearIllBe() constant returns (uint8){
return age + 1;
}
function newBirthDay() { <-- gas used 26991
age = nextYearIllBe();
}
}
Ambas funciones de cumpleaños realizan la misma operación de adición y almacenamiento, pero la newBirthDay
función también agrega una llamada adicional a su flujo.
alper
alper
Edmundo Edgar
alper