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();
}
Ich habe auch versucht, die Vertragsadresse wie from: contract_address
in 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!
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:
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 resellTicket
Funktion von dem Konto aufzurufen, das die Rückerstattung wünscht.
gffbss
natewelch_
gffbss
natewelch_
gffbss
Error: Transaction has been reverted by the EVM
natewelch_
increaseInventory
natewelch_
resellTicket
? Diese Funktion ist nicht kostenpflichtig