Könnten wir eine konstante Funktion aufrufen, ohne Gas innerhalb einer Transaktionsfunktion auszugeben?

Ich habe eine sortierte verknüpfte Liste, die ungefähr 1000 Elemente enthält. Wenn ich einen neuen Artikel erhalte, ist es mein Ziel, den Artikel in die Liste zu verschieben, wobei die sortierte Reihenfolge beibehalten wird. Wenn ich also einen sehr kleinen Wert erhalte, muss ich die gesamte Liste durchlaufen, um das Ende der Liste zu finden.

Das Ziel der konstanten Funktion besteht darin, den Indexspeicherort zurückzugeben, in den die Transaktionsfunktion verschoben werden soll.

Iteration(iterateListToFindPushIndex()) könnte so aussehen:

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

Wie wir wissen, kostet der Aufruf einer konstanten Funktion kein Gas und ist kostenlos zu verwenden. Wenn ich also die Indexposition über eine konstante Funktion finde, kostet mich das kein Benzin.

function iterateListToFindPushIndex() constant returns(uint index){}
function func(intervalNode storage self) { 
  index = iterateListToFindPushIndex();
  self.list.push(Interval( { num: s, next: index }) )
}

Wenn ich in einer Transaktionsfunktion durch meine Liste iteriere, obwohl ich keinen Speicher ändere, kostet mich das zusätzliches Benzin.

Ist es also möglich, eine konstante Funktion aufzurufen, ohne Gas innerhalb einer Transaktionsfunktion auszugeben?

Vielen Dank für Ihre wertvolle Zeit und Hilfe.

Antworten (3)

Der Aufruf einer constantFunktion innerhalb einer Transaktion kostet genauso viel wie der Aufruf einer Nicht- constantFunktion innerhalb einer Transaktion. Das constantheißt, da es den Zustand nicht ändert, kann Ihr lokaler Knoten es ausführen und Ihnen das Ergebnis mitteilen, ohne dass eine Transaktion erforderlich ist. Das kostet kein Gas, da nur Ihr Knoten die Berechnung durchführen muss.

Sie können dies möglicherweise verwenden, um Gas in einer Transaktion zu sparen, indem Sie zuerst die Konstantenfunktion aus Ihrem JavaScript-Code ausführen, um ein Ergebnis zu erhalten, und dieses Ergebnis dann als Parameter an die Transaktion übergeben. Wenn Ihr Vertrag der sendenden Person jedoch nicht vertraut, müssen Sie ihn dennoch innerhalb der Transaktion verifizieren. Dies kann immer noch nützlich sein: Wenn Sie eine sortierte Liste haben und wissen möchten, wo ein Element abgelegt werden soll, kann es nützlich sein, es auf der Clientseite zu überprüfen und den Index zu finden x, den Index xals Transaktionsparameter zu übergeben und dann zu lassen der Smart-Contract-Code in der Transaktion überprüft, ob der Artikel bei x-1vor dem steht, was Sie hinzufügen, und der Artikel bei x+1danach kommt.

Ein Fallstrick besteht darin, dass sich die Daten zwischen dem Lesen eines Ergebnisses und dem Senden eines Aufrufs, der es enthält, an die Blockchain in einer Transaktion ändern können. In diesem Fall schlägt Ihre Transaktion fehl und Sie müssen sie erneut senden.

Bezogen auf Ihren Vorschlag: Der beste Block der Blockchain ist beispielsweise 100. Aber mein Knoten befindet sich derzeit bei Blocknummer 90 (im Grunde hinter der Blockchain). Wenn ich also Ihren Vorschlag mache, kann der Knoten des Clients den Index der Liste bis zu den ersten 90 Blöcken erhalten und Elemente verpassen, die auf den verbleibenden 10 Blöcken generiert wurden. Kann ich überprüfen, ob die Blocknummer meines Knotens mit der besten und neuesten Blocknummer der Blockchain übereinstimmt? Wenn das möglich ist, wird Ihre Lösung funktionieren. Andernfalls wird der Client nicht wissen, ob sein Knoten mit der Kette synchronisiert wird, und kann den Index der Listenbasis auf fehlenden Elementen finden. @EdmundEdgar
Bitte beachten Sie, dass es eine andere Frage zu sein scheint, die ich in einem anderen Thread gestellt habe: ethereum.stackexchange.com/q/13863/4575
Wenn Sie nach „latest“ fragen, erhalten Sie den neuesten Block, den Ihr Knoten sehen kann. Ihr Knoten sollte normalerweise nicht mehr als ein paar Sekunden hinter dem Rest des Netzwerks zurückbleiben, sobald die Synchronisierung abgeschlossen ist. Wenn es, wie Sie sagen, ständig hinterherhinkt, sollten Sie vielleicht eine andere Frage stellen.
Ich arbeite an einer privaten Kette. Wie Sie auf dem Bild sehen können (ethereum.stackexchange.com/q/13863/4575), kommt mein Knoten manchmal 10 oder vielleicht mehr Blöcke hinterher. Aber irgendwann alle auf dem neuesten Block. Daher ist es in meinem Fall schwierig, dem Verhalten des Knotens zu vertrauen. @EdmundEdgar

Wie wir wissen, kostet der Aufruf einer konstanten Funktion kein Gas und ist kostenlos zu verwenden.

Diese Aussage ist falsch. Ich würde gerne wissen, was die Quelle dieser Aussage ist, da sie korrigiert werden sollte.

Eine Transaktion ändert per Definition den Zustand der Ethereum-Blockchain, verschiebt ETH oder Bits.

Wenn Transaktionen Berechnungen durchführen, verwenden sie die CPU-Zeit von Minern. Nicht nur Miner, sondern auch CPU-Zeit aller Ethereum Full Nodes, da derzeit jede Transaktion auf jedem Node gespielt wird. Bergleute sind nicht gemeinnützig und stellen Ihnen natürlich Gebühren für die Nutzung ihrer CPU in Rechnung. Es spielt keine Rolle, ob die Unteraufrufe oder Berechnungen den Zustand verändern (nicht konstant) oder keine Seiteneffekte haben (konstant), wenn das Gesamtergebnis der Transaktion die Änderung von nur einem Bit in der Ethereum-Blockchain ist.

Das Aufrufen einer konstanten Funktion ist nur kostenlos, wenn Sie den Status von Ihrem lokalen Knoten abfragen, da Sie dann keine Transaktion durchführen, sondern nur einen RPC-Abfrageaufruf an Ihre lokale Blockchain-Datenbank.

Hochgestimmt. Ständige Anrufe können leicht einige Punkte übersehen; eine verwandte Erklärung ist ethereum.stackexchange.com/questions/10906/…
Mit anderen Worten, das Schreiben und Lesen von Bots kostet Gas?

Die Anruffunktion constantkann Ihren Gasverbrauch erhöhen . Die EVM muss nun eine weitere Funktion abrufen und dem Stack hinzufügen, um den richtigen Wert zu berechnen. Sehen Sie sich zum Beispiel den folgenden Code an:

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

Beide Geburtstagsfunktionen führen denselben Additions- und Speichervorgang aus, aber die newBirthDayFunktion fügt Ihrem Flow auch einen zusätzlichen Aufruf hinzu.