He escrito un servidor API simple NodeJS
que usa web3
(versión 1 beta 27) para interactuar con un nodo de paridad remoto.
La tripa de la llamada es la siguiente
const invoke = async (req, res) => {
const { params: { address } } = req
try {
const theContract = new web3.eth.Contract(abi, contractAddress, { from: SENDER_ADDRESS })
const fn = theContract.methods.doTheThing(address)
const account = web3.eth.accounts.privateKeyToAccount(PRIVATE_KEY)
const data = fn.encodeABI()
const nonce = await web3.eth.getTransactionCount(SENDER_ADDRESS, 'pending')
const payload = {
nonce,
data,
gas,
from: SENDER_ADDRESS,
to: contractAddress
}
const signedTx = await account.signTransaction(payload, account.privateKey)
const { rawTransaction } = signedTx
const response = await web3.eth.sendSignedTransaction(rawTransaction)
const { transactionHash: tx } = response
res.json({ tx })
} catch (err) {
res.status(500).json({ error: err.message })
}
}
Esto funciona perfectamente si solo hago una llamada a la API a la vez, e incluso funciona bien si hago algunas llamadas que se superponen aproximadamente. (lo probé con curl usando varias ventanas de terminal)
Pero si uso un script para llamar a la API muchas veces simultáneamente (que es una simulación razonable de una condición del mundo real), la mayoría de las llamadas fallan y dicenThere is another transaction with same nonce in the queue.
Una solución que me recomendaron es crear una personal
dirección dentro de Parity en lugar de crear una dirección en forma de un par de claves pública/privada en mi máquina, pero esa no parece ser la mejor solución.
El problema es que web3.eth.getTransactionCount(SENDER_ADDRESS, 'pending')
devuelve lo mismo nonce
si la API se invoca demasiado rápido. Una idea es que simplemente podría volver a intentarlo si el error detectado incluye el There is another transaction with same nonce in the queue.
mensaje, pero eso parece frágil, por decir lo menos.
¿Cuál es la forma correcta de poner en cola solicitudes simultáneas como esta?
Puede usar la solicitud por lotes, le permite enviar transacciones de un pedido específico:
http://web3js.readthedocs.io/en/1.0/web3-eth.html?highlight=batch#batchrequest
poliani
cámaras de barney