Estoy tratando de enviar muchas transacciones a Ethereum con un programa escrito en js. Uso node js, web3 e infura ropsten. El problema es: si envío transacciones a la vez, la mayoría de ellas simplemente desaparecen. Tratando de resolver este problema, envío transacciones con intervalos. Funciona, pero muy lentamente. Paso una hora para enviar solo 100 transacciones. ¿Hay alguna solución para que funcione más rápido y correctamente? Estaba pensando en enviar la transacción después de que la anterior comenzara a estar pendiente, pero no veo cómo puedo hacerlo. La función sendRaw obtiene el número de transacción solo después de un tiempo. Este código lee el archivo, obtiene la dirección, la cantidad y los datos opcionales y utiliza el método de contrato inteligente para transferir tokens. Aquí está el código:
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();
La mayor parte de la confusión con el manejo de grandes volúmenes de transacciones se deriva de suposiciones ocultas que afectarán a escala.
Hay algunos hechos importantes y no obvios para entender.
Implícitamente, se sigue que:
Por último:
Es posible enviar transacciones rápidamente pero exige precisión a nivel de transacción. Las cosas pueden salir mal, como:
Las transacciones faltantes son ambiguas. De hecho, se pueden extraer si uno espera lo suficiente, o es posible que nunca se extraigan. La ambigüedad es un problema para las actividades no triviales a escala. El proceso necesita hacer algo proactivo para eliminar la ambigüedad.
Para cada transacción, incremente el nonce y envíe, luego espere a que la transacción aparezca en la cadena con confirmaciones. Después de unos minutos, comience a lidiar con el caso de falla.
Para el uso diario, puede ser suficiente enviar una transacción de cancelación. Aquí hay un truco útil para "desbloquear" una billetera que envió una transacción con un precio de gas demasiado bajo. La cuenta debe enviarse cero éter a sí misma especificando el nonce de la transacción a cancelar y un gasPrice mayor que la transacción a cancelar. Cuando la transacción de reemplazo aparece en un bloque, la transacción original (cualquiera que haya sido) no se extraerá, debido al precio más alto del gas y al nonce idéntico: una cancelación confirmada. Es recomendable esperar varias confirmaciones como lo haría con cualquier otra transacción.
El mismo principio se puede aplicar al reintento. Utilice los mismos datos y nonce que la transacción que falta y un gasPrice más alto. Esto implica que el remitente está administrando el nonce a medida que avanza y conoce los datos, la carga útil, el nonce y el precio de gas de cada transacción que envió para que pueda abordar las fallas de transacción con precisión.
Para obtener más información sobre los problemas técnicos, eche un vistazo a la discusión de Singleton Nonce Manager aquí: Patrones de simultaneidad para cuenta nonce
Espero eso ayude.
¿ Quizás los métodos por lotes web3 1.0 funcionarían?
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();
Este era un problema común en el mundo de los juegos, por lo que se formuló EIP 1155 . Usted y otros pueden beneficiarse de tratar únicamente con ERC-1155 o envolviendo los tokens de interés (suponiendo que sean ERC-20 o ERC-721) en ERC-1155.
alan buxton
ismael
Tomas Clowes
Ayushya
hhppj