Fehler während der Vertragsausführung [Schlechte Anweisung]

Ich verstehe nicht, warum ich diesen Fehler in der Transaktion erhalte, wenn ich meine Funktion mit web3.js ausführe:

Warnung! Fehler während der Vertragsausführung [Schlechte Anweisung]

Ich habe diese andere Frage zu demselben Fehler gelesen. Ich verstehe nicht, warum mit diesem Code dasselbe passiert:

contract Music is owned{

    string public themeMusic;
    string public idMusic;
    int public money;

    function Music (string setThemeMusic, string setIdMusic, int setmoney) {
        themeMusic = setThemeMusic;
        idMusic = setIdMusic;
        money = setmoney;
    }

    function setMoney(int moneyUpdate) onlyOwner {
        money = moneyUpdate;
    }
}

Der Fehler liegt bei der setMoney-Funktion, ist für das onlyOwner? muss ich es payabletrotzdem machen? Ich möchte es nicht machen payable, sondern es nur zum Setzen des Geldes verwenden und diese Funktion nur für das Eigentum.

Mehr Informationen:

  • Ich mache andere Verträge mit ähnlichen Funktionen und habe dieses Problem nicht.
  • Dieser Vertrag wird durch einen anderen Vertrag wie die typische Beispielfabrik erstellt.
  • Owned ist ein Vertrag, bei dem ich die Adresse speichere und teste, ob ich der Besitzer bin.
  • Ich benutze Meteor.jsund Web3.js.

Wie gehen Sie mit dem Vertrag um? Für die Interaktion mit dem Vertrag verwende ich die Web3.js APi von Ethereum.

Welchen Befehl verwendest du ? Ich definiere den Vertrag mit der ABI und die Adresse des Vertrags so myContract = web3.eth.contract(ABIArray).at(contractAddress);und rufe dann die Funktion des Vertrags so auf myContract.setMoney(money);(und die Callback-Funktion).

Verwenden Sie Produktions-Blockchain? Ich arbeite im Ropsten Testnet.

Mein Musikunternehmen:

contract musicCompany is owned {

    address[] public listofmusic;

    function addMusic(string setThemeMusic, string setIdMusic, int setmoney) onlyOwner {
        address newMusic = new Music(setThemeMusic, setIdMusic, setmoney);
        listofmusic.push(newMusic);
    }
}

Dieser Vertrag kann einen neuen Musikvertrag erstellen.

Mein eigener Vertrag:

contract owned {

    address public owner;

    function owned() {
        owner = msg.sender;
    }

    modifier onlyOwner {
        if (msg.sender != owner) throw;
        _;
    }

}

Mein Web3.js-Code:

'click .setMoney'(event, instance) {
     var price = document.getElementById('priceUpdate').value;
     event.preventDefault();
     alert("contract price");
     myContract.setMoney(price, function(error, result){
      if(!error)
          console.log(result);
      else
          console.error(error);
      })

Screenshot der Metamask-Transaktionen ohne Probleme:

Screenshot der Metamask-Transaktionen ohne Probleme

Screenshot der EtherScan.io-Transaktion mit dem Fehler:Screenshot der EtherScan.io-Transaktion mit dem Fehler:

Update 1: Ich versuche, vorzeichenlose Ganzzahlen und bytes32 anstelle von int zu verwenden, das Ergebnis ist dasselbe. Vielleicht liegt das Problem im Modifikator, könnte es sein?

Update 2:onlyOwner Ich habe versucht, den Modifikator der Funktion zu löschen , und es funktioniert nicht ...

Update 3: Ich habe versucht, alle Modifikatoren zu löschen, is ownedund onlyOwnerfunktioniert immer noch nicht. Ich denke, das Problem liegt bei der Builder-Funktion, ich werde jetzt anfangen, damit zu testen ...

Update 4: Durch Testen weiß ich, dass moneyUpdateder Wert korrekt und moneygleich ist, aber ich habe festgestellt, dass sich der Wert von moneynicht ändert. Und ich habe auch festgestellt, dass ich die Adresse der Transaktion erhalte, wenn ich die Ergebnisvariable meines Rückrufs in "My Web3.js-Code" drucke 0x0fda5d31d02c87aa20c45a54f6859c7576b4f0aae4a639c47ec23e5c4e‌​3d9953. Im Prinzip wird die Transaktion durchgeführt, aber der Fehler verhindert die Änderung.

Einige Transaktionen (alle sind meine) zum Anzeigen des Fehlers:

0x52ef9164750c4e174cba1a5f45343220458f1cedca25380f0aaf102df0a8f895

0x4e00d9d67ffb906e0036434ea2e14acea82a6aabb4d8c99d94c0b2bcdef24f7a

0x4663fa874993d54989d073f72d6846cae652a454349e62882dccc96d78528a8e

0x69fbf54ffd81ee114efcd750d4e97bb528ecc868140abdecf218e9ae66391a5

Können Sie einen Link zu einer der fehlgeschlagenen Transaktionen bereitstellen?
Ja, Sie haben eine in der Antwort, aber ich kann mehr sagen.
Generell empfehle ich die Verwendung des Truffleframeworks für die Entwicklung. github.com/trufflesuite/truffle Es beseitigt viele Probleme wie diese sofort und hilft Ihnen, flüssiger loszulegen.
@NikitaFuchs Ja, ich kenne das Framework, aber diese Entwicklung hat mit Meteor begonnen... Jetzt kann ich nicht mehr wechseln oder gibt es eine einfache Migration?
Mit Truffle erhalten Sie versprochene Funktionen gemäß den Funktionsnamen in Ihrem Vertrag, einfacher geht es nicht.

Antworten (4)

Der Code ist so offensichtlich einfach, dass das einzige Problem mit onlyOwner zu sein scheint. Ich würde den Wert der ownerVariablen überprüfen. Ich wette, es ist nicht das, was du denkst. (Es ist entweder null oder der Wert des Absenders, der den Vertrag bereitgestellt hat). ownerSie haben die Vertragsadresse nicht angegeben, daher kann ich den Wert von auf Etherscan nicht überprüfen . Außerdem geben Sie nicht die Adresse des Anrufkontos an. Wenn sie nicht übereinstimmen, wird die Transaktion ausgelöst, was (wie bei allen Ethereum-Fehlern) zu einem Gasmangel führt. Wenn der Code wirklich so einfach ist, wie Sie sagen, besteht das einzig mögliche Problem mit owner. Das würde ich prüfen.

Ich werde es versuchen und dann kommentiere ich etwas, ich stelle einige Transaktionen auf die Frage, ob Sie dies überprüfen möchten.
Ich lösche alle Verweise auf die Eigentümerklasse in diesem Vertrag und in dem Vertrag, der den Musikvertrag erstellt hat, und es funktioniert, aber wenn ich es erneut einfüge, schlägt es fehl ... Was ist passiert?
Während der Initialisierung wird die Besitzervariable entweder auf eine andere Kontoadresse als die, die Sie denken, gesetzt, oder sie wird überhaupt nicht gesetzt (und ist daher null). Sie sollten in der Lage sein, dies anhand der Registerkarte „ReadContract“ auf etherscan.io zu erkennen. Jemand hat oben kommentiert, dass es keinen Konstruktor in Ihrem Code gibt, was meiner Meinung nach bedeutet, dass der „Besitzer“ Null ist. Wie lautet die Adresse? Ich kann es überprüfen.
Sie müssen den vollständigen Quellcode für den Vertrag oder einen Verweis darauf über GitHub oder so bereitstellen. Wenn es ohne isOwnerund nicht mit funktioniert, dann ist der Wert von ownernicht auf msg.sender gesetzt. (Wenn Sie sich den Eigentümervertrag ansehen, können Sie sehen, dass isOwnernur geworfen wird, wenn die Werte nicht übereinstimmen. Der Grund dafür ist, dass Sie höchstwahrscheinlich nicht festlegen owner. Vielleicht fehlt mir etwas. Die tatsächliche vollständige Quelle zu sehen, würde helfen .
Ja, ich habe es behoben, mit Ihrem Tipp ist die in „isOwner“ festgelegte Adresse nicht mit der Vertragsmusik identisch. Wenn ich also den Modifikator „onlyOwner“ verwende, funktioniert dies nicht, da diese Adresse der übergeordnete Vertrag ist. Dieser Fehler führt dazu, dass ich den gesamten Code viele Male ändere ... für nur eine falsche Adresse.
Der ownerwird im Konstruktor mithilfe von festgelegt msg.sender, bei dem es sich um die Adresse des Kontos handelt, das den Vertrag bereitgestellt hat. Wenn Sie eine durch later geschützte Funktion aufrufen isOwnerund die Adresse, die diesen Aufruf initiiert, nicht mit derjenigen übereinstimmt, die den Vertrag bereitgestellt hat, wird ein Fehler ausgegeben. Es scheint mir, dass Sie sich entschieden haben, das zu entfernen, isOwnerwas vielleicht nicht die beste Idee ist. Sie sollten den richtigen Eigentümer anrufen, sonst verlieren Sie den Schutz, den der ownedVertrag bietet. Danke für das Kopfgeld.
Nein, mach dir keine Sorgen um isOwner, ich teste, um das Problem mit zu beheben, isOwneraber mein Hauptproblem "Identifizieren Sie, wo das Problem hier liegt und warum dies passiert" ist gelöst. Jetzt habe ich ein anderes Problem mit den Adressen, die die Funktion ausführen und warum sie nicht mit den anderen übereinstimmen. Ich werde den letzten Teil meines Codes einfügen, falls Sie eine Idee haben, dass das falsch ist.
Aktualisiert mit dem letzten Teil der Vertragsinteraktion, das ist alles. Wenn Sie eine Idee haben, können Sie mir mit einem Kommentar antworten. (Vielleicht war das Problem die Vertragserstellung, ich teste jetzt darüber)
An dieser Stelle würde ich vorschlagen, dass Sie die Frage stark vereinfachen und eine neue Frage stellen, und sie werden mehr Antworten von anderen Leuten bekommen.

Ihre Transaktion scheint fehlgeschlagen zu sein, weil Sie sie von einer anderen Adresse aus anrufen, als Sie sie erstellt haben. Ich ging durch die erste Transaktion und bemerkte, dass ISZERO + JUMPIbeim Vergleich mit dem Anrufer ein Gleichheitstest ( ) übersprungen wurde. Sicher genug, diese Transaktion wurde von gesendet 0x178597064fc55ea505c3ea066c154d92bc264943, aber der Vertrag wurde von erstellt0xc2351205ee14cdb8b61ffc826ad1906bc7c08755

Also, wie Thomas gepostet hat , liegt das Problem tatsächlich am onlyOwnerModifikator.

Es wäre hilfreich, den Code für den ownedVertrag zu sehen, von dem Sie erben. Ich würde mir vorstellen, dass es nicht viel mehr tut, als auf ownerzu setzen msg.sender, aber es könnte einige zusätzliche Komplikationen geben.

Unabhängig davon, wenn Sie versuchen, 0xc2351205ee14cdb8b61ffc826ad1906bc7c08755bei der ersten Transaktion von an den Vertrag zu senden, sollte es funktionieren.

Neben weiteren netten Details (Wie interagieren Sie mit dem Vertrag? Welchen Befehl verwenden Sie?) müssen Sie dem Vertrag eine Konstruktorfunktion hinzufügen. Versuchen Sie auch, vorzeichenlose Ganzzahlen anstelle von int zu verwenden.

contract Music is owned{

    string public themeMusic;
    string public idMusic;
    int public money;

    function Music() {
    // this is the constructor, do something here or leave it empty
    }
    function Car (string setThemeMusic, string setIdMusic, uint setmoney) {
        themeMusic = setThemeMusic;
        idMusic = setIdMusic;
        money = setmoney;
    }

    function setMoney(uint moneyUpdate) onlyOwner {
        money = moneyUpdate;
    }
Entschuldigung, Auto ist nicht der korrekte Name der Funktion, Auto ist der Musikkonstruktor, der für andere Funktionen in anderen Verträgen aufgerufen wird, die die Verträge generieren. Ich behebe es in der Frage.

Ich habe Ihren Code getestet und er funktioniert gut (ich habe den ownedTeil in dieselbe Datei gelegt). Ich habe trufflemit testrpc(ich habe einen JS-Test geschrieben und ausgeführt). Vielleicht liegt das Problem darin, wie Sie Ihren Vertrag bereitstellen/mit ihm interagieren.

Nebenbemerkung: Die Funktion muss sein, payablewenn Sie Ether senden, indem Sie sie aufrufen (Sie möchten Ether durch Funktionsaufruf empfangen). Hier sendest du kein echtes Geld, sondern legst nur den Wert fest.

Ich verwende meteor.jsund diese Struktur funktioniert gut in anderen meiner Verträge, mit der gleichen Set-Funktion und den gleichen Funktionen der web3.js API, und hier, wenn ich diese Funktion ausführe (weil diese Funktion nur nicht funktioniert, funktionieren die anderen Funktionen gut) erscheint dieser Fehler in Etherscan und die Transaktion wird nicht gut verarbeitet, sodass ich das Geld nicht wechseln kann.
Sind Sie sicher, dass priceSie an setMoney einen ganzzahligen Wert senden? Haben Sie es mit fest codierten Werten versucht, z. B. 10 ?
Hey Lukasz, ich versuche, den Wert fest zu codieren, und es passiert dasselbe, aber wenn ich den Ethereum-Scan zum Anzeigen der Transaktion verwende, habe ich in der Dateneingabe die Zahl erhalten, aber sie ist hexadezimal, das ist normal? so was:[0]:000000000000000000000000000000000000000000000000000000000000000a
@Gawey Ich weiß es wirklich nicht. Probieren Sie das nachstehende Verfahren aus. 1. Was gibt die Callback-Funktion aus? 2. Versuchen Sie, ein Ereignis (das den Wert von moneyund enthält moneyUpdate) auszugeben, nachdem Sie den Wert festgelegt haben, und erfassen Sie das Ereignis im Browser und drucken Sie es aus. 3. Versuchen Sie, den Geldwert aus dem Vertrag abzulesen. Vielleicht wurde es aktualisiert und es ist nur ein Etherscan-Fehler. 4. Verwenden Sie Produktions-Blockchain?
Für die 2) und 3) Frage ist alles in Ordnung, moneyUpdatehabe den Wert korrekt und moneygleich, aber ich habe festgestellt, dass sich der Wert von moneynicht ändert. Für 4) arbeite ich im Ropsten-Testnetz. Für 1) habe ich festgestellt, dass ich resultdie Adresse der Transaktion erhalte, wenn ich die Variable meines Rückrufs in "My Web3.js-Code" drucke 0x0fda5d31d02c87aa20c45a54f6859c7576b4f0aae4a639c47ec23e5c4e3d9953, eine Idee? Im Prinzip wird die Transaktion durchgeführt, aber der Fehler verhindert die Änderung.
Momentan keine bessere Idee. Gib mir einfach Bescheid, wenn du es repariert hast, ich bin gespannt, was falsch war.
Ok, danke, ich werde ein Kopfgeld für die Antwort anbieten, hahahaha