So erstatten Sie eine Wallet-Adresse aus einem Vertrag mit solidity und web3

Ich baue eine App, in der ich möchte, dass ein Käufer eine Rückerstattung aus dem Vertrag beantragen kann. Im Wesentlichen versuche ich, eth von einem Vertrag in eine Brieftasche zu übertragen. Wenn ich an den Punkt komme, an dem ich eine Rückerstattung ausstelle, zeigt die Transaktion in MetaMask, dass meine Brieftasche auf den Vertrag übertragen wird, nicht umgekehrt, wie ich möchte. Ich benutze web3 und solidity. Hier ist meine js-Funktion, die von dem Konto aufgerufen wird, das eine Rückerstattung anfordert:

window.resellTicket = async function () {    
// send a refund from contract to reseller
try {
  // Call resell method from contract
  const resell = TicketEvent.methods.resellTicket();
  await resell.send({'value': web3.utils.toHex(web3.utils.toWei('.1234', "ether"))});

} catch (err) {
  console.log(err);
}     
load();
}

Die ResellTicket-Methode in meinem Vertrag:

function resellTicket() public payable {
  msg.sender.transfer(ticketPrice);
  isHoldingValidTicket[msg.sender] = false;
  increaseInventory();
}

Was ich in MetaMask sehe:Geben Sie hier die Bildbeschreibung ein

Ich habe auch versucht, die Vertragsadresse wie from: contract_addressin meiner Funktion resellTicket js fest zu codieren. In diesem Fall erhalte ich diesen Fehler:Error: Returned error: Error: WalletMiddleware - Invalid "from" address.

Ich stecke hier total fest, wäre für jede Anleitung dankbar!

Antworten (2)

Ich kann nicht verstehen, warum der Benutzer ETH mitschicken muss oder möchte, wenn er eine Rückerstattung beantragt. Das bedeutet auch, dass Ihre Wiederverkaufsfunktion nicht kostenpflichtig sein sollte.

Um die Frage zu beantworten (auch wenn sie sehr alt ist, könnte sie noch jemandem helfen), gibt es mehrere mögliche Ursachen für diese Ablehnung, die sich aus dem von Ihnen gezeigten Code ergeben:

  1. Sie sollten den Wei-Betrag nicht in Hex umwandeln, dies führt zu unerwarteten Ergebnissen und kann in einigen Fällen auch zu einer Rücksetzung führen. Der von web3.utils.toWei zurückgegebene Wert ist so wie er ist vollkommen in Ordnung.
  2. ticketPrice sollte irgendwo in Ihrem Vertrag definiert sein
  3. raiseInventory() könnte der Übeltäter sein
  4. Der Vertrag hat möglicherweise nicht genug ETH

Die Verwendung von Remix und seinem Schritt-für-Schritt-Debugger hilft dabei, die genaue Position des Zurücksetzens zu identifizieren.

Abschließend, und das ist der wichtigste Teil , der anderen Lesern hoffentlich helfen wird, diese Art von Fehlern zu vermeiden:

Diese Wiederverkaufsfunktion ist anfällig für einen sehr einfachen Angriff, selbst wenn Sie require(isHoldingValidTicket[msg.sender]);ganz am Anfang oder als Modifikator hinzufügen, wie Sie es sowieso tun sollten.

  msg.sender.transfer(ticketPrice);
  isHoldingValidTicket[msg.sender] = false;
  increaseInventory();

Die erste Zeile sendet ETH an den msg.sender, der ein bösartiger Smart Contract sein könnte. Sein Fallback würde auslösen und könnte möglicherweise erneut zum Weiterverkauf aufrufen und eine weitere Rückerstattung erhalten, und zwar immer wieder, bis das Gas ausgeht oder die gesamte ETH abgelassen wird. Zwar sollte die Übertragung davor schützen, indem sie nur sehr wenig Gas (2300) weiterleitet, aber solche Beschränkungen können manchmal umgangen werden, zB indem andere Schwachstellen ausgenutzt werden, was großen Schaden anrichtet; Das Verschieben einer Codezeile während der Entwicklung ist billig und in diesem Fall nur eine bewährte Methode, die eine ganze Klasse von Angriffen vollständig zunichte machen kann.

Sie sollten immer dem Checks-Effects-Interactions-Muster folgen und die ETH zuletzt senden.

Wenn Sie mehrere externe Interaktionen in derselben Funktion haben, achten Sie sehr darauf, wie sie angeordnet sind und welche Korrelation sie haben.

Verträge können keine Transaktionen senden, nur Konten können dies. Was Sie tun müssen, ist die resellTicketFunktion von dem Konto aufzurufen, das die Rückerstattung wünscht.

Vielen Dank für Ihre Rückmeldung, die ResellTicket-Funktion wird bereits von dem Konto aufgerufen, das die Rückerstattung wünscht.
Was ist dann das Problem? Diese Funktion gibt die Rückerstattung bereits aus, Sie müssen nichts weiter tun
Das Problem ist, dass die Transaktion fehlschlägt.
Welchen Fehler bekommst du?
Error: Transaction has been reverted by the EVM
Bei diesem Fehler weist der Vertrag entweder kein ausreichendes Guthaben auf oder es liegt ein Fehler vorincreaseInventory
Oh eigentlich, warum schickst du eth an resellTicket? Diese Funktion ist nicht kostenpflichtig