Eine Funktion, die einem Array in der Blockchain eine Struktur hinzufügt, wird nicht ausgeführt, wenn sie von einer anderen Funktion aufgerufen wird

Ich habe ein Problem, das wahrscheinlich sehr grundlegend ist, aber ich kann das Problem nicht herausfinden

function _CreateBike(uint id, uint generation, string model, string ability, uint8 tier) internal returns(Bike){
    Bike memory bike = Bike(id, generation, 1, tier, model, ability, msg.sender);
    garage.push(bike);
    return bike;
}

Ich habe diese Funktion oben, die eine Struktur erstellt und in ein Array schiebt, und sie funktioniert wie beabsichtigt

function BuyBike(string model, string ability, uint8 tier) public payable costs(basePrice*tier) {
    Bike memory bike = _CreateBike(garage.length, current_generation, model, ability, tier);
    ownedBikes[msg.sender] = [bike.id];
}

Wenn ich jedoch diese Funktion ausführe, die die frühere Funktion aufruft, wird die Struktur nicht zum Array hinzugefügt. Ich gehe davon aus, dass dies etwas mit Referenzvariablen und der Speicherung in der Blockchain im Vergleich zum lokalen Speicher zu tun hat, aber ich kann immer noch nicht herausfinden, wie ich das Problem beheben kann, nachdem ich Stackoverflow und die Solidity-Dokumente überprüft habe. Kann mir bitte jemand sagen was los ist?

Ihrer zweiten Funktion scheint ein Semikolon zu fehlen. Das sollte nicht kompilieren. Stellen Sie sicher, dass Sie den tatsächlichen Code teilen, den Sie verwenden.
Sicher, ich habe den Code bearbeitet, um ihn etwas allgemeiner zu gestalten, aber ich habe meine Frage so geändert, dass sie den tatsächlichen Code enthält.
Dieser Code scheint für mich gut zu funktionieren. Ich habe a mit den sieben Feldern erstellt, struct Bike { ... }die Sie passiert haben, und a Bike[] public garageund a hartcodiert uint current_generation = 1, ich habe den costsModifikator von gelöscht BuyBike, und dann habe ich aufgerufen BuyBike("model", "ability", 8)und überprüft, dass beide garage[0]und garage[1]die erwartete Bike-Struktur in ihnen waren. _CreateBike(Es wird zweimal hinzugefügt, da es sowohl in als auch hinzugefügt wird BuyBike.)
Sieht so aus, als hättest du gerade eines der pushes fallen gelassen. Mit dieser Änderung wird es nur einmal hinzugefügt garage. (Ich habe auch die ownedBikesZeile gelöscht, anstatt eine andere Variable zu deklarieren.)
Ich sollte hinzufügen, dass meine Tests in Remix über die JavaScript-VM stattfanden. Wenn Sie immer noch Probleme sehen, teilen Sie uns vielleicht anderen relevanten Code mit (wie die eigentlichen Variablendeklarationen und den von Ihnen verwendeten Modifikator), teilen Sie uns mit, wie Sie den Vertrag bereitstellen und testen, und zeigen Sie uns, wie Sie aufrufen BuyBikeund wie Sie das Ergebnis überprüfen.
Das ist seltsam, ich führe den Code auf remix.ethereum.org aus und BuyBike funktioniert bei mir nicht wie vorgesehen. [ remix.ethereum.org/… mein Code), funktioniert es dort auch bei dir? Ich stelle gerade den Vertrag bereit, kaufe ein Fahrrad und verwende die getBike-Methode, und ich erhalte einen Fehler, der auftritt, wenn dem Array keine Strukturen hinzugefügt werden.
Es scheint, als hätten Sie versucht (und sind gescheitert), auf Ihren Code zu verlinken. Können Sie es einfach in Ihre Frage hier aufnehmen?
Auch nur eine Vermutung, aber versuchen Sie, den costsModifikator aus zu entfernen BuyBike. Ich vermute, dass dieser Modifikator einen bestimmten Wert in erwartet msg.value, und ich weiß nicht, wie ich Ether über Remix an eine Transaktion anhängen soll.
Das hat funktioniert! Ich habe den Kostenmodifikator entfernt und es ging ohne Probleme durch. Ich kann nicht glauben, dass ich nicht daran gedacht habe. Vielen Dank! Ich bin neu beim Stack Exchange, wie kann ich Ihre Kommentare positiv bewerten?
Hoffentlich verstehen Sie jetzt, warum es wichtig ist, den eigentlichen Code, den Sie testen, zu teilen. :-) Wenn Sie vereinfachen, versuchen Sie zuerst, den vereinfachten Code auszuführen, und vergewissern Sie sich, dass Sie das Problem immer noch sehen. (In diesem Fall hätte Ihr vereinfachter Code, sobald er für die Kompilierung korrigiert wurde, das Problem nicht gezeigt, und das hätte Sie dazu bringen können, die Lösung zu finden.)
Ich habe eine Antwort hinzugefügt, damit Sie diese als richtig markieren können.

Antworten (2)

Zusammenfassen der Kommentare zu einer Antwort:

Das Problem ist der costsModifikator, der vermutlich msg.value. Da es (soweit ich weiß) keine Möglichkeit gibt, Ether an eine Transaktion in Remix anzuhängen, wenn die JavaScript-VM verwendet wird, gibt es keine Möglichkeit, die msg.valueAnforderung zu erfüllen, also ist die Funktion vermutlich reverted.

Ich habe das gerade getestet und kann Ether an einen Vertrag senden, indem ich das Feld "Wert" unten verwende, wo die Umgebung in Remix ausgewählt ist.

Ergänzend zur Antwort von smarx besteht eine Möglichkeit zum Testen in einer eher produktionsähnlichen Umgebung darin, ein privates Netz zu verwenden, bei dem es sich entweder um Ganache oder Ganache-Cli handeln kann, oder um ein benutzerdefiniertes privates Testnetz, das mit Geth erstellt wurde. Ich bin mir sicher, dass es andere Optionen gibt, aber das sind die, die ich verwende und von denen ich weiß, dass sie funktionieren.

Freundlicher Haftungsausschluss: Einige private Testnetze haben ihre eigenen Probleme (z. B. Ganache hat keine Unterstützung für Websockets, daher funktionieren Events nicht mit web3 1.0, private Testnetze mit Geth können andere Konsensalgorithmen haben als Mainnet), also verwenden Sie sie nicht als letzten Test, bevor Sie den Code an das Hauptnetz senden, es sei denn, Sie sind sicher, dass Ihr Code auf die gleiche Weise funktioniert.