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 payable
trotzdem 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:
Meteor.js
und 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 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 owned
und onlyOwner
funktioniert 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 moneyUpdate
der Wert korrekt und money
gleich ist, aber ich habe festgestellt, dass sich der Wert von money
nicht ä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 0x0fda5d31d02c87aa20c45a54f6859c7576b4f0aae4a639c47ec23e5c4e3d9953
. 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
Der Code ist so offensichtlich einfach, dass das einzige Problem mit onlyOwner zu sein scheint. Ich würde den Wert der owner
Variablen ü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). owner
Sie 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.
isOwner
und nicht mit funktioniert, dann ist der Wert von owner
nicht auf msg.sender gesetzt. (Wenn Sie sich den Eigentümervertrag ansehen, können Sie sehen, dass isOwner
nur 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 .owner
wird 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 isOwner
und 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, isOwner
was vielleicht nicht die beste Idee ist. Sie sollten den richtigen Eigentümer anrufen, sonst verlieren Sie den Schutz, den der owned
Vertrag bietet. Danke für das Kopfgeld.isOwner
aber 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.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 + JUMPI
beim 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 onlyOwner
Modifikator.
Es wäre hilfreich, den Code für den owned
Vertrag zu sehen, von dem Sie erben. Ich würde mir vorstellen, dass es nicht viel mehr tut, als auf owner
zu setzen msg.sender
, aber es könnte einige zusätzliche Komplikationen geben.
Unabhängig davon, wenn Sie versuchen, 0xc2351205ee14cdb8b61ffc826ad1906bc7c08755
bei 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;
}
Ich habe Ihren Code getestet und er funktioniert gut (ich habe den owned
Teil in dieselbe Datei gelegt). Ich habe truffle
mit 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, payable
wenn 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.
meteor.js
und 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.price
Sie an setMoney einen ganzzahligen Wert senden? Haben Sie es mit fest codierten Werten versucht, z. B. 10 ?[0]:000000000000000000000000000000000000000000000000000000000000000a
money
und 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?moneyUpdate
habe den Wert korrekt und money
gleich, aber ich habe festgestellt, dass sich der Wert von money
nicht ändert. Für 4) arbeite ich im Ropsten-Testnetz. Für 1) habe ich festgestellt, dass ich result
die 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.
AbweichenFisch
Gawey
Nikita Fuchs
Gawey
Nikita Fuchs