Warum einige interne Transaktionen erfolgreich sein können und andere fehlschlagen

https://ropsten.etherscan.io/tx/0x8d5b9a6906b9f287c4b09333272f691a75655e470c128b78b3bc4a540c534190
In this transaction, I tried to send 10wei to 0x0000000000000000000000000000000000000000, 0x0000000000000000000000000000000000000001,
.....
0x0000000000000000000000000000000000000009
But the ethes sent to 0x0000000000000000000000000000000000000001 and several other accounts have failed, and the other part war erfolgreich. Ich weiß nicht, warum das so ist. Dies ist der Quellcode des Vertrages.

  function getThisBalance() payable returns(uint, uint){
  for (uint i = 0; i < msg.value; i ++){
      address(i).send(1);
  }
  return (i, msg.value);

}

Antworten (2)

Der Grund, warum Ihr Senden für bestimmte Adressen (z. B. address(1)) fehlschlägt, ist, dass diese Adresse eigentlich ein Vertrag ist (auch wenn es auf etherscan.io nicht so aussieht).

Diese Adressen sind vorkompilierte Verträge (z. B. der ECDSA-Wiederherstellungsvertrag), nehmen Sie also zusätzliches Gas, um Geld zu senden. Sie können zusätzliches Gas geben, wenn Sie die ETH senden, um dies zu umgehen, oder einen anderen Adressbereich verwenden, um vorkompilierte Verträge zu vermeiden, wenn die Adressen für Sie nicht wichtig sind.

Vorkompilierte Verträge erwarten auch, dass Eingabeparameter gültig sind, wenn sie nicht einen Fehler verursachen.
Vielen Dank für Ihre Antwort. Können Sie mir sagen, wie man Gas in der internen Transaktion angibt?
Sie können etwas verwenden wie: msg.sender.call.gas(2500000).value(amount)()um eine größere Gasmenge anzugeben. NB - der Grund, dies nicht zu tun, ist, dass es dem Vertrag, an den Sie Geld senden, ermöglicht, wieder in Ihren Vertrag einzutreten (da er jetzt das Gas dafür hat). Für vorkompilierte bekannte Verträge ist dies nicht unbedingt ein Problem, aber gefährlich, wenn ETH an unbekannte Verträge gesendet wird.

address.sendüberweist Ether auf das angegebene Konto. Wenn es sich bei diesem Konto um einen Smart Contract handelt, wird seine Fallback-Funktion ausgeführt.

Standardmäßig ist die Fallback-Funktion eines Smart Contracts nicht payable. Das heißt, es kehrt zurück, wenn Ether an es gesendet wird. Wenn also eine Ihrer Adressen die eines Smart Contracts ist, der keine payableFallback-Funktion hat, address.sendwird falsch zurückgegeben und der Ether wird nicht an diesen Smart Contract gesendet. Die Transaktion wird jedoch fortgesetzt, da Ihr Code nichts mit dem Rückgabewert von tut address.send.

Ein weiterer Grund für address.senddas Scheitern ist, dass nur 2300 Gas mitgeschickt werden. Ein Smart Contract, der über eine payableFallback-Funktion verfügt, kann Ether nur dann empfangen, address.sendwenn die Ausführung der Fallback-Funktion nicht mehr als 2300 Gas kostet. Es ist möglich, ein Ereignis mit 2300 Gas auszusenden, aber nicht viel mehr.

Um mehr als 2300 Gas an die Fallback-Funktion zu senden, können Sie verwenden address.call.value([wei])(), um das gesamte Gas weiterzuleiten, oder address.call.value([wei]).gas([gas])(). address.callgibt false zurück, wenn es fehlgeschlagen ist, und truewenn es erfolgreich war.

Jedoch!

address.callist eine potenzielle Sicherheitsbedrohung. Es könnte eine Re-Entrancy-Schwachstelle einführen . Aus diesem Grund wird von der Verwendung abgeraten.

Vielen Dank für Ihre Antwort. Können Sie mir sagen, wie man Gas in der internen Transaktion angibt?