Abheben von Ethereum aus einem Smart Contract (Rückgabe an den Absender)

Nehmen wir an, ich habe eine dezentrale Anwendung, die es Menschen ermöglicht, ein Objekt zu einem beliebigen Preis zu kaufen.

Benutzer 1 kauft das Objekt für 1 eth. Wenige Augenblicke später kauft Benutzer 2 denselben Artikel. Wie kann ich dieses Ereignis überwachen und automatisch die entsprechende Menge Etherium an Benutzer 2 zurückgeben? Hier ist, was ich bisher habe:

contract Adoption {
    address[16] public adopters;

    function returnEth() public payable {
    msg.sender.transfer(msg.value);
    }
    // Adopting a pet
    function adopt(uint petId) public payable returns (uint) {
        require(petId >= 0 && petId <= 15);
        //require(msg.value == 1 ether);
        adopters[petId] = msg.sender;
        returnEth();
        return petId;
        //return value;
    }
    // Retrieving the adopters
    function getAdopters() public view returns (address[16]) {
        return adopters;
    }


}
Ihre zweite Frage hat nichts mit der ersten zu tun. Ich würde vorschlagen, es als neue Frage zu stellen. (Es ist für andere schwierig, von Ihrer Frage zu profitieren oder sie zu beantworten, wenn sie in einer anderen Frage vergraben ist.)

Antworten (1)

Wenn Sie zwischen den Zeilen lesen, sagen Sie, dass Benutzer 2 nicht berechtigt sein sollte, den Artikel zu kaufen, den Benutzer 1 bereits gekauft hat.

Wenn dies der Fall ist, sollte der Anruf des Benutzers 2 zum Kauf des Artikels fehlschlagen. Sie haben die Funktion, die zum Tätigen eines Kaufs verwendet wird, nicht freigegeben, aber sie sollte die Transaktion rückgängig machen, wenn der Artikel bereits verkauft ist.

Was passiert, wenn die Transaktion noch bestätigt wird?
Eine Transaktion, die noch nicht bestätigt wurde, wartet nur herum. Es hat keine Wirkung. Wenn es schließlich verarbeitet wird, wird es entweder erfolgreich sein (wenn es der erste ist, der den Artikel kauft) oder fehlschlagen.
Das sind gute Informationen, aber ich würde trotzdem gerne wissen, wie man Ether aus dem Vertrag an Benutzer sendet. Soll ich meine ursprüngliche Frage aktualisieren?
Es ist nur <address>.transfer(<amount>).
Würde mein ursprünglicher Code also theoretisch funktionieren, wenn er zum richtigen Zeitpunkt aufgerufen würde?
Wenn Benutzer A für Ihren ursprünglichen Code 1 Ether an die Funktion sendet, überträgt er 1 Ether an Benutzer A. Wenn Sie aus irgendeinem Grund die Transaktion nicht einfach rückgängig machen möchten, scheint dies eine gute Möglichkeit zu sein, die übertragenen zu erstatten Äther.
Okay. Wenn ich diese Funktion in meinem Vertrag aufrufen wollte (es ist dieselbe wie die, auf die Sie auf meine letzte Frage geantwortet haben), wie würde ich das mit web3js machen? Ich möchte StackExchange einfach nicht mit Fragen zuspammen.
Um es von einer anderen Funktion in Ihrem Vertrag aufzurufen, tun Sie einfach returnEth();. Wenn Ihre Frage "Wie rufe ich eine Funktion aus web3.js auf?" das scheint nicht verwandt zu sein. Bitte stellen Sie es als neue Frage, aber lesen Sie zuerst einfach ein Tutorial, vielleicht sogar meins: programtheblockchain.com/posts/2017/12/13/… . (Ich denke jedoch, dass Sie vielleicht Truffle verwenden? Wenn ja, schauen Sie sich stattdessen ein Tutorial dafür an.)
also werde ich nicht mehr über das web3js-Ding sprechen, aber wenn ich returnEth(); In meinem bestehenden Vertrag wird eth von meiner Metamask-Brieftasche abgezogen, aber nicht zurückgegeben. Wissen Sie, warum dies passieren könnte?
Nein. Ein direkter Anruf returnEth()sollte niemals die Menge an Ether auf dem Konto des Anrufers verringern. Selbst wenn dies transferfehlschlägt, wird die Transaktion rückgängig gemacht, sodass sich kein Äther bewegt.
1 eth wird von ihrer Brieftasche von der adopt()-Funktion in meiner vorherigen Frage abgezogen. returnEth() wird innerhalb von adopt() aufgerufen, aber es scheint nicht zu funktionieren.
Sie müssten den tatsächlichen Code, den Sie verwenden, freigeben (ich denke, der aktuelle Code für adoptdiese Aufrufe returnEth.)
aktualisierte meine Frage mit dem vollständigen Code
Der Code in Ihrer Frage funktioniert gut für mich. Beachten Sie, dass Gasgebühren in jedem Fall anfallen, sodass der Ether-Saldo des Kontos bei jeder Transaktion um einen kleinen Betrag sinken sollte. Aber wenn ich mit 100 Ether starte und 1 Ether an sende adopt(), lande ich nach dem Aufruf bei >99.99999999 Ether.