Mehrere Transaktionen von derselben Adresse

Ich möchte mehrere Transaktionen von derselben Adresse gleichzeitig erstellen. Da jede Transaktion Nonce benötigt (TX-Zähler der Absenderadresse), kann ich Geth nach dem aktuellen Zählerstand fragen und das erste TX erstellen, dann Nonce erhöhen und das nächste erstellen und so weiter. Probleme, wie ich sie sehe, sind:

  1. Wenn eine Transaktion nicht abgebaut wird, wird keine der folgenden Transaktionen abgebaut (da Nonce falsch ist).
  2. was passiert, wenn einige tx in einen block und einige in den anderen block aufgenommen werden, die reihenfolge könnte falsch werden. Ist diese Überlegung richtig?

Wenn dies nicht der Fall ist, frage ich mich, ob es für diesen Fall einen besseren Ansatz gibt.

Mich würde zuerst interessieren, was passiert, wenn Sie ~ 10-20 Transaktionen "auf einmal" senden und an welchem ​​​​Punkt es fehlschlägt. Bitte melden Sie sich zurück.
Tayvano, Test von 30 Transaktionen auf einmal unten. Der Test wurde auf der Blockchain durchgeführt, wo ich die Nonce nicht angegeben habe.
@BokkyPooBah Bitte vermeiden Sie es, einen Kommentar als Antwort zu posten. Ein Link könnte wahrscheinlich verwendet werden, um lange Kommentare zu vermeiden.
Jawohl. August gewöhnt sich an dieses System.

Antworten (3)

Sie haben nicht angegeben, ob Sie Ihre Transaktionen senden, während Sie über Geth (On-Blockchain) mit der Blockchain verbunden sind, oder ob Sie Ihre Transaktion erstellen, während Sie nicht mit der Blockchain verbunden sind (Off-Blockchain).

Die Antwort von Paul S. bezieht sich auf das Erstellen von Transaktionen außerhalb der Blockchain, bei dem Sie eine Nonce in den Rohtransaktionen angeben müssen, die Sie dann auf der Blockchain ausführen.

Wenn Sie Ihre Transaktion über die Blockchain senden, können Sie eth.sendTransaction(...) ohne weiteres verwenden.

Hier sind zum Beispiel 3 Transaktionen vom gleichen „Von“-Konto zum gleichen „Bis“-Konto. Es ist nicht erforderlich, eine Nonce anzugeben, da sie automatisch generiert wird:

> eth.sendTransaction({from: '0x5e83b635f96da0752f991f0ebddc31249f452dea', to: '0x68acc3a13441b69016560d23e134c7931bbb27bb', value: web3.toWei(1, "ether")});
"0x92d6d2285b198b6b5cf80eca6d4292c9675fb53f47f786063df600d3be06dd09"
> eth.sendTransaction({from: '0x5e83b635f96da0752f991f0ebddc31249f452dea', to: '0x68acc3a13441b69016560d23e134c7931bbb27bb', value: web3.toWei(2, "ether")});
"0x0c1280c8b2f38aec032494913c1d0e65edd511fcd15e2424483f9bbf51c7172e"
> eth.sendTransaction({from: '0x5e83b635f96da0752f991f0ebddc31249f452dea', to: '0x68acc3a13441b69016560d23e134c7931bbb27bb', value: web3.toWei(3, "ether")});
"0x8b6998eea8b343a0f754cf2732a1f28caac3acdfbe97cca69f244f0614ea546a"

> eth.getTransaction("0x92d6d2285b198b6b5cf80eca6d4292c9675fb53f47f786063df600d3be06dd09");
{
  blockHash: "0x8456088424a4cacd8b394b4e11732e3c96ca77ab4a999c6ba62b38ab61116b58",
  blockNumber: 225,
  from: "0x5e83b635f96da0752f991f0ebddc31249f452dea",
  gas: 90000,
  gasPrice: 20000000000,
  hash: "0x92d6d2285b198b6b5cf80eca6d4292c9675fb53f47f786063df600d3be06dd09",
  input: "0x",
  nonce: 0,
  to: "0x68acc3a13441b69016560d23e134c7931bbb27bb",
  transactionIndex: 0,
  value: 1000000000000000000
}
> eth.getTransaction("0x0c1280c8b2f38aec032494913c1d0e65edd511fcd15e2424483f9bbf51c7172e");
{
  blockHash: "0x8456088424a4cacd8b394b4e11732e3c96ca77ab4a999c6ba62b38ab61116b58",
  blockNumber: 225,
  from: "0x5e83b635f96da0752f991f0ebddc31249f452dea",
  gas: 90000,
  gasPrice: 20000000000,
  hash: "0x0c1280c8b2f38aec032494913c1d0e65edd511fcd15e2424483f9bbf51c7172e",
  input: "0x",
  nonce: 1,
  to: "0x68acc3a13441b69016560d23e134c7931bbb27bb",
  transactionIndex: 1,
  value: 2000000000000000000
}
> eth.getTransaction("0x8b6998eea8b343a0f754cf2732a1f28caac3acdfbe97cca69f244f0614ea546a");
{
  blockHash: "0x8456088424a4cacd8b394b4e11732e3c96ca77ab4a999c6ba62b38ab61116b58",
  blockNumber: 225,
  from: "0x5e83b635f96da0752f991f0ebddc31249f452dea",
  gas: 90000,
  gasPrice: 20000000000,
  hash: "0x8b6998eea8b343a0f754cf2732a1f28caac3acdfbe97cca69f244f0614ea546a",
  input: "0x",
  nonce: 2,
  to: "0x68acc3a13441b69016560d23e134c7931bbb27bb",
  transactionIndex: 2,
  value: 3000000000000000000
}
Ich benutze web3.js den ganzen Tag (verbunden mit Geth als Anbieter), ohne mit der Nonce herumzuspielen. Wer stellt die Nonce für mich ein?
Paul S, von github.com/ethereum/go-ethereum/blob/master/rpc/api/… es scheint, dass die Nonce erraten wird, wenn sie nicht angegeben ist.
hört sich so an, als ob für die Nonce eine separate Frage benötigt wird. Also suchte ich nach dem Wort „nonce“. da gibt es viel gutes zu lernen. Keine Notwendigkeit für eine separate Frage.
@PaulS fragt sich, ob Sie herausgefunden haben, wie Sie dies tun und Nonce mit web3.js festlegen? oder wie sende ich mehrere trx?

Wenn Sie Transaktionsabhängigkeiten in Ihrer Off-Blockchain-Anwendung haben, sollten Sie warten, bis die vorherige Transaktion abgebaut wurde, bevor Sie die nächste Transaktion einreichen.

Im Allgemeinen ist der Prozess

  1. Senden Sie eine Transaktion, das Ergebnis ist ein Transaktions-Hash
  2. Busy poll oder wait on event, um zu sehen, ob die Transaktion für diesen Hash-Wert abgebaut wurde.

Es gibt keine guten prägnanten Beispiele dafür, die ich in einen Stackexchange-Beitrag einfügen kann, aber hier sind einige Links, die verschiedene Möglichkeiten zeigen, dies zu tun:

So erkennen Sie, wann Ihre Transaktion abgebaut wurde Stack Exchange Frage

Ether Pudding hat dies eingebaut, sehen Sie sich also die Zeitsynchronisierung in index.js an, um zu erfahren, wie das funktioniert. Macht Ihren Anwendungscode mithilfe von Versprechungen sehr sauber. Allerdings ist index.js ziemlich schwer zu lesen ... vertrau mir einfach, es funktioniert ;-)

Sie können den Transaktionsbeleg abfragen

Sie können die Transaktion abfragen, um zu sehen, ob ihr Block gültig ist . Das macht Ätherpudding.

Sie können einen Ereignisfilter erstellen , dessen Rückruf bei jedem abgebauten Block ausgelöst wird, und jedes Mal, wenn ein Block abgebaut wird, können Sie eine der oben genannten Abfragemethoden verwenden, um zu sehen, ob Ihre Transaktion abgebaut wurde. Dies ist möglicherweise besser als beschäftigtes Polling, obwohl ich einige Probleme mit dem Eventing-System hatte, die sehr schwer zu reproduzieren sind.

In all diesen Fällen möchten Sie nicht ewig warten, sondern eine Art Auszeit. Im Allgemeinen werden Sie in Javascript entweder einen Rückruf an Ihre Anwendung auslösen oder ein erfülltes Versprechen zurückgeben, wenn eine Transaktion abgebaut wird. Ich nehme an, Sie könnten einige der anderen Javascript-Idiome wie RXJS oder Event verwenden, aber ich habe diese für diesen Zweck nicht ausprobiert.

Müssen sie alle gleichzeitig sein, oder können Sie eine willkürliche Verzögerung von beispielsweise 30 Sekunden einfügen, bevor die nächste ausgelöst wird? Dies würde sicherlich alle von Ihnen beschriebenen Probleme beseitigen. Viel kürzere Zeiten könnten fast sicher verwendet werden.

Es besteht die reale Möglichkeit, dass Transaktionen nicht in der gleichen Reihenfolge gesendet / verarbeitet werden und daher fehlschlagen, aber dies hängt vom gelieferten Gas, dem Grad der Netzaktivität, der tatsächlichen Geschwindigkeit „gleichzeitig“ usw. ab.

30 Sekunden zu warten ist nicht ratsam, da die Mining-Zeiten variieren können. Wenn Sie Auftragsabhängigkeiten zwischen Transaktionen haben, warten Sie, bis die vorherige Transaktion abgebaut ist, da dies eine positive Bestätigung ist. Zu einem fortgeschritteneren Thema, wenn Sie sich Sorgen über doppelte Ausgaben machen, warten Sie, bis mehrere Blöcke abgebaut wurden, nachdem die Transaktion abgebaut wurde.
@PaulS Aufgrund der Nonce gibt es keine Möglichkeit, doppelt auszugeben. Senden Sie eine Transaktion mit einer Nonce von 0, dann 1, dann 2. Wenn die erste nicht abgebaut wird, schlagen die erste und die zweite fehl. Wenn 2 vor 1 "ankommt", wird es ähnlich fehlschlagen. Wenn Sie sie alle mit einer Nonce von 0 senden, wird nur die erste abgebaute durchgehen. Etc. Etc. Ich glaube, 30 Sekunden reichen aus, aber ich werde hier in ein paar Minuten selbst einen Test machen.
Was passiert, wenn gelegentlich ein Block vom Blockchain-Protokoll zurückgesetzt wird? Wenn Sie sich außerhalb der Blockchain befinden, denken Sie vielleicht, dass Sie Ether gesendet haben, aber das haben Sie tatsächlich nicht. IMHO müssen Sie dies für einige kritische Arten von Transaktionen nachverfolgen. (Auf Blockchain ist es in Ihrem Solidity-Code nicht relevant, da der Block zurückgesetzt wird und Ihr Zustand damit zurückgesetzt wird.)
Die web3.js-Dokumentation enthält mehrere Beispiele für das Warten auf das Mining einer Transaktion. Meiner Erfahrung nach sind magische Timeouts sehr zerbrechlich.
@PaulS Warum postest du nicht das web3-Beispiel als Antwort, da es in diesem Zusammenhang sicherlich nützlich ist
Übrigens, wenn Sie sich nicht um die Reihenfolge kümmern, können Sie sie einfach gleichzeitig einreichen. Ich habe jeweils hundert in der Standardparallelität für Bluebirds Promise.map eingereicht, mit Geth scheint es gut zu funktionieren, bis das maxGas des Blocks überschritten wird.
Hat das die Nonce für Sie berechnet? Wie hast du das gehandhabt?
Ich habe mir nie Sorgen um die Nonce gemacht. AFAICT, es gibt etwas Magie in entweder web3.js oder in Geth, das sich für mich um die Nonce kümmert. Wenn es dringend ist, kann ich versuchen, diesen Code wiederzubeleben, ich habe Sachen getestet und die Testfallgenerierung aufgrund eines dieser lustigen Ereignisfehler auf solide verschoben.