Wie man viele Transaktionen mit js an Ethereum sendet

Ich versuche, viele Transaktionen mit einem in js geschriebenen Programm an Ethereum zu senden. Ich verwende node js, web3 und infura ropsten. Das Problem ist: Wenn ich Transaktionen auf einmal sende, verschwinden die meisten einfach. Um dieses Problem zu lösen, sende ich Transaktionen mit Intervallen. Es funktioniert, aber sehr langsam. Ich verbringe Stunden damit, nur 100 Transaktionen zu senden. Gibt es eine Lösung, wie es schneller und richtiger funktioniert? Ich habe darüber nachgedacht, eine Transaktion zu senden, nachdem die vorherige ausstehend ist, aber ich sehe nicht, wie ich das tun kann. Die Funktion sendRaw erhält die Transaktionsnummer erst nach einiger Zeit. Dieser Code liest die Datei, ruft Adresse, Betrag und optionale Daten ab und verwendet die Methode des Smart Contract, um Token zu übertragen. Hier ist Code:

function sendRaw(rawTx) {
var privateKey = new Buffer(key, 'hex');
var transaction = new tx(rawTx);
transaction.sign(privateKey);
var serializedTx = transaction.serialize().toString('hex');
web3.eth.sendRawTransaction(
'0x' + serializedTx, function(err, result) {
    if(err) {
        console.log(err);
    } else {

        console.log(result);
        Ntrans=result;
    }
});
}


var nonce = web3.eth.getTransactionCount(address);
var gasPrice = web3.eth.gasPrice;
var gasLimit = 90000;

var fs = require("fs");
var buf1 = new Buffer(1024);
var buf2 = new Buffer(1024);
var buf3 = new Buffer(1024);
var i = 0;
var j = 0;
var k = 0;

var fd = fs.openSync('/home/kate/Desktop/file.txt', 'r+');


function recurs()
{
    if(k==5) return -1;
    j = 0;
    do
    {
          fs.readSync(fd, buf1, j, 1, i);
          i++;
          j++;
    }
    while(buf1[j-1] != 32);
    AddressC = String(buf1.slice(0, j-1))
    console.log(AddressC);
    j = 0;
    do
    {
          fs.readSync(fd, buf2, j, 1, i)
          i++;
          j++;
    }
    while(buf2[j-1]!=32);
    ValueT = Number(buf2.slice(0, j-1))
    console.log(ValueT);
    j = 0;
    do
    {
          fs.readSync(fd, buf3, j, 1, i);
          i++;
          j++;
    }
    while(buf3[j-1]!=10);
    TxC = String(buf3.slice(0, j-1));

    txOptions =
    {
         nonce: web3.toHex(nonce),
         gasLimit: web3.toHex(gasLimit),
         gasPrice: web3.toHex(gasPrice),
         to: contractAddress

    }

    console.log(TxC);
    console.log(txOptions);
    rawTx = txutils.functionTx(interface, 'foreignBuy', [AddressC, 
    ValueT, TxC], txOptions);
    sendRaw(rawTx);
    k++;
    nonce++;
   /* while(web3.eth.getTransactionReceipt(Ntrans)=="null")
    {

    } */
}

setTimeout(function(){
    recurs();
}, 5000);
}
recurs();
Ich vermute, dass dies ein Fehler ist – siehe github.com/ethereum/go-ethereum/issues/14893
Infura ist ein öffentlicher Dienst, der als Sicherheitsmaßnahme eine Art Ratenbegrenzung hat. Wenn Sie eine höhere Begrenzung wünschen, sollten Sie sich an sie wenden.
Können Sie bitte auch Ihren Code formatieren, damit er für potenzielle Antwortende besser lesbar ist.
Es ist alt, aber wenn Sie Fortschritte gemacht haben, posten Sie bitte Ihre Antwort.
Wir wechselten zu Alchemy ( alchemyapi.io ), nachdem wir mit den gleichen Ratenbegrenzungsproblemen und Zuverlässigkeitsbedenken von Infura konfrontiert waren. Ich würde empfehlen, dasselbe für alle Anwendungen in Produktionsqualität zu tun.

Antworten (3)

Die meiste Verwirrung bei der Handhabung großer Transaktionsvolumina rührt von versteckten Annahmen her, die sich in großem Maßstab bemerkbar machen.

Es gibt einige wichtige und nicht offensichtliche Fakten zu verstehen.

  1. Transaktion Nonce wird vom Absender verwaltet.
  2. Transaktionen vom selben Absender werden in Nonce-Reihenfolge abgebaut.

Daraus folgt implizit:

  1. Wenn eine Transaktion nicht abgebaut wird, können Transaktionen mit einer höheren Nonce nicht abgebaut werden. Eine Lücke würde gegen Nr. 2 verstoßen, und deshalb kann ein Konto so aussehen, als wäre es blockiert.

Zuletzt:

  1. Miner haben die volle Entscheidungsfreiheit, Transaktionen in Blöcke aufzunehmen oder sie zu ignorieren.

Es ist möglich, Transaktionen schnell einzureichen, erfordert jedoch Präzision auf Transaktionsebene. Dinge können schief gehen, wie zum Beispiel:

  1. GasPreis zu niedrig
  2. Transaktion verloren (kein Grund)

Fehlende Transaktionen sind mehrdeutig. Sie können tatsächlich abgebaut werden, wenn man lange genug wartet, oder sie werden möglicherweise nie abgebaut. Mehrdeutigkeit ist ein Problem für nicht-triviale Aktivitäten im großen Maßstab. Der Prozess muss etwas Proaktives tun, um die Mehrdeutigkeit zu beseitigen.

Erhöhen Sie für jede Transaktion die Nonce und senden Sie sie, und warten Sie dann, bis die Transaktion mit Bestätigungen in der Kette erscheint. Beginnen Sie nach einigen Minuten mit der Bearbeitung des Fehlerfalls.

Für den täglichen Gebrauch kann es ausreichen, eine Stornierungstransaktion zu senden. Hier ist ein praktischer Trick, um eine Brieftasche zu „entstören“, die eine Transaktion mit einem zu niedrigen Gaspreis gesendet hat. Das Konto sollte null Ether an sich selbst senden, wobei die Nonce der zu stornierenden Transaktion und ein gasPrice angegeben werden, der höher ist als die zu stornierende Transaktion. Wenn die Ersatztransaktion in einem Block erscheint, wird die ursprüngliche Transaktion (was auch immer es war) aufgrund des höheren Gaspreises und der identischen Nonce - einer bestätigten Stornierung - nicht abgebaut. Es ist ratsam, wie bei jeder anderen Transaktion auf mehrere Bestätigungen zu warten.

Das gleiche Prinzip kann auf den Wiederholungsversuch angewendet werden. Verwenden Sie die gleichen Daten und Nonce wie die fehlende Transaktion und einen höheren gasPrice. Dies impliziert, dass der Absender die Nonce im laufenden Betrieb verwaltet und die Daten, Payload, Nonce und GasPrice jeder gesendeten Transaktion kennt, sodass er Transaktionsfehler präzise ansprechen kann.

Um mehr Einblick in die technischen Probleme zu erhalten, werfen Sie einen Blick auf die Singleton Nonce Manager-Diskussion hier: Concurrency Patterns for Account Nonce

Ich hoffe es hilft.

Vielleicht würden die Batch-Methoden von web3 1.0 funktionieren?

var contract = new web3.eth.Contract(abi, address);

var batch = new web3.BatchRequest();
batch.add(web3.eth.getBalance.request('0x0000000000000000000000000000000000000000', 'latest', callback));
batch.add(contract.methods.balance(address).call.request({from: '0x0000000000000000000000000000000000000000'}, callback2));
batch.execute();

Dies war ein häufiges Problem in der Spielewelt, weshalb EIP 1155 formuliert wurde. Sie und andere können davon profitieren, entweder nur mit ERC-1155 zu handeln oder die interessierenden Token (vorausgesetzt, es handelt sich um ERC-20 oder ERC-721) in ERC-1155 zu verpacken.