Vertragswert mit Konsolenaufruf auf truffle / testrpc erhöhen, Variable ist nicht persistent

Was ich tun möchte, ist einen intelligenten Vertrag zu erstellen, der eine Variable hat, die einen Wert ansammeln kann. Ich möchte, dass es als beginnt 0und es dann erhöht, während ich regelmäßig überprüfe, ob meine Aufrufe zum Erhöhen des Werts tatsächlich funktioniert haben.

Hier ist mein sehr einfacher Smart Contract, um das zu erreichen:

pragma solidity ^0.4.13;

// This contract demonstrates a simple non-constant (transactional) function you can call from geth.
// increment() takes no parameters and merely increments the "iteration" value. 

contract Incrementer {
    uint iteration;

    function Incrementer() {
        iteration = 0;
    }

    function increment(uint count) {
        iteration += count;
    }

    function getIteration() constant returns (uint) {
        return iteration;
    }

}

Es muss jedoch kaputt sein, oder ich nenne es vielleicht nicht richtig, wie Sie an meiner Konsolenausgabe sehen können:

Geben Sie hier die Bildbeschreibung ein

Die Ausführungsumgebung, die ich verwende, ist truffle.

Die Befehle zum Kompilieren waren:

truffle compile --all
truffle migrate --reset

Dann starte ich, um damit truffle consolezu interagieren, nachdem ich testrpcin einem anderen Fenster begonnen habe.

Die genauen Befehle, die ich verwendet habe, waren:

Incrementer.deployed()

Incrementer.deployed().then(function(instance) { meta = instance; return meta.getIteration.call(); })

und alternativ:

Incrementer.deployed().then(function(instance) { meta = instance; return meta.increment.call(1); })

Wie kann ich den Wert von iteration()erhöhen, indem ich increment()aufrufe und dann das Ergebnis mit ausgebe getIteration()?


BEARBEITEN:

Geben Sie hier die Bildbeschreibung ein

Antworten (2)

Eines der korrekten Verfahren ist nach meinen Experimenten, auf diese Weise aufzurufen:

Incrementer.deployed().then(function(instance) { meta = instance; return meta.increment(1); })

Ausgabe sieht so aus:

Geben Sie hier die Bildbeschreibung ein

überprüfen Sie auf diese Weise:

Incrementer.deployed().then(function(instance) { meta = instance; return meta.getIteration(); })

ergibt:

Geben Sie hier die Bildbeschreibung ein

Zwei Dinge springen heraus und einige Stilhinweise.

Erstens und wahrscheinlich am wichtigsten

Bei Dir ist return meta.getIteration.call()das .call()Teil überflüssig (aber harmlos). Es ist überflüssig, da die Vertragsfunktion markiert ist constantund daher nur auf dem lokalen Computer ausgeführt wird, nicht netzwerkverifiziert. Es sollte genauso gut (und genauso) ohne funktionieren .call().

Aber Sie bekommen Probleme, wenn Sie .call()das .increment()tun, weil Sie ausdrücklich sagen, dass Sie die lokale Ausführung, den verifizierungsfreien, schreibgeschützten Ausführungsmodus wollen. Daher übermittelt es keine Transaktion an das Netzwerk. Ergo, macht nicht das, was Sie erwarten.

Zweite

Sie könnten die erste Hürde überwinden und dann auf die nächste stoßen. Nach dem Ablegen .call()werden die Dinge sendTransaction()tief unten in den Modus versetzt, und Sie erhalten einen txnHashstatt eines Rückgabewerts. Das ist normal.

Stil

Ich würde publicin beiden Funktionen schreiben, um eine Gewohnheit im Einklang mit Best Practices zu entwickeln. Es ist die Standardeinstellung, es ändert sich also nichts. Außerdem würde ich return(bool success)oder return(uint newCount)zugunsten anderer Verträge.

Ich hoffe es hilft.

Aktualisieren

Halten:

var contract;
var counter;

Incrementer.deployed()
.then(function(instance) {
  contract = instance;
  return contract.increment(1);
})
.then(function(txnHash) {
  return contract.getIteration();
})
.then(function(response) {
  var counter = response.toString(10);
  console log("Counter says:", counter);
});

Ich gehe hier nur Freestyle, also hoffe ich, dass ich es nicht vermasselt habe.

Ich habe es ohne .call()on incrementund auch versucht getIteration, aber es scheint in diesem Fall nur die Methodensignatur oder so etwas zurückzugeben. Ich habe die Konsolenausgabe unter der letzten Bearbeitung des OP gepostet. Bitte verzeihen Sie mir meine Unwissenheit, aber ich bin mir nicht sicher, was Sie damit meinen return(bool success). Können Sie mir vielleicht zeigen, wie das als Teil einer dieser Funktionen aussehen würde? Trotzdem vielen Dank für diese Hinweise, ich schätze Ihre Ratschläge sehr.
meta.getInteraction().then(...Undmeta.increment().then(...
Wie wäre es mit der Antwort, die ich gerade gepostet habe? scheint zu funktionieren
Scheint, als ob du in die richtige Richtung gehst. Ich habe meiner ursprünglichen Antwort einen Gedanken hinzugefügt. Gibt dir vielleicht ein paar Ideen.
Ich habe versucht, diese Incrementer()Methode aufzurufen, um sie auf Null zurückzusetzen, und das hat nicht funktioniert. Können Sie diese Art von Konstruktormethoden aus irgendeinem Grund nur einmal aufrufen?
Ja. Konstruktor feuert einmal und nur einmal. Es ist nicht verfügbar.
aha, okay cool. Ist das wie ein allgemeines Programmierparadigma? Dass Konstruktoren nur einmal ausgelöst werden und dass Sie keine Methode mit demselben Namen aufrufen können wie der ... wie lautet der Name-Contract? oder Klasse oder so
In Solidity ist ein Konstruktor eine Funktion mit dem gleichen Namen wie der Vertrag und wird während des Deployments einmal ausgelöst, wobei der Deployer die Ausführungskosten trägt. Es ist ungefähr ähnlich wie init() in anderen Sprachen. Niemand kann es anrufen.
aha, ok cool, gut das zu wissen. hast du vielleicht zufällig eine gute, dh aktuelle etc. quelle, wie man einen vertrag wie diesen bei ropsten einsetzt? Ich habe vergeblich versucht, diesen hierher zu schieben