¿Cómo puedo obtener los últimos 10 datos de bloques usando web3.js como lo hace la mayoría de los exploradores de bloques?
Hay algunos problemas con la respuesta aceptada:
.getBlock()
y .getBlockNumber()
ambos son asincrónicos, por lo que si se crea un nuevo bloque durante el ciclo, no solo ya no obtendrá los bloques "más recientes", sino que también tendrá duplicados.Para resolver la primera inquietud, debe mantener una referencia al último número de bloque:
const latest = await web3.eth.getBlockNumber()
Para reducir la cantidad de solicitudes de red web3, puede usar BatchRequests .
const batch = new web3.eth.BatchRequest()
batch.add(web3.eth.getBlock.request(blockNumber, callback))
batch.execute()
Tenga en cuenta que para pasar los argumentos a la función, debe usar el request
método especial.
Poniéndolos juntos, puede recuperar los últimos n bloques con:
const latest = await web3.eth.getBlockNumber()
const blockNumbers = _range(latest - n, latest + 1, 1)
const batch = new web3.eth.BatchRequest()
blockNumbers.forEach((blockNumber) => {
batch.add(
web3.eth.getBlock.request(blockNumber, storeLocalCopy)
)
})
batch.execute()
Usar web3.eth.getBlock
conweb3.eth.blockNumber
for (var i=0; i < 10; i++) {
console.log(web3.eth.getBlock(web3.eth.blockNumber - i));
}
EDITAR: para web3.js 1.0+ el cuerpo del ciclo debe ser:
web3.eth.getBlock(web3.eth.blockNumber - i).then(console.log)
( ejemplo )
web3.eth.blockNumber
en la variable local antes de hacer un bucle en caso de que llegue un nuevo bloqueExiste la funcionalidad de filtro disponible dentro de la biblioteca web3.js que está extremadamente bien documentada. Está diseñado exactamente para ese propósito.
También vale la pena consultar la documentación de JSONRPC para comprender cómo funciona esta funcionalidad entre bastidores.
Copie/pegue de los documentos con una ligera modificación:
var filter = web3.eth.filter({toBlock:'latest'});
filter.watch(function (error, log) {
console.log(log); // {"address":"0x0000000000000000000000000000000000000000", "data":"0x0000000000000000000000000000000000000000000000000000000000000000", ...}
});
// get all past logs again.
var myResults = filter.get(function(error, logs){ ... });
...
// stops and uninstalls the filter
filter.stopWatching();
Puede combinar getBlockNumber
(recuperar el último número de bloque) y getBlock
. Dado que ambas funciones son asíncronas, usaremos Promise.then
y async/await
. Código completo en NodeJs
var http = require('http');
var Web3 = require('web3');
var w3 = new Web3("ws://localhost:8546");
async function queryBlock(i){
var json = await w3.eth.getBlock(i);
return json;
}
var server = http.createServer((req,res)=>{
res.statusCode = 200;
res.setHeader('Content-Type','application/json');
var blocks = [];
w3.eth.getBlockNumber().then((n) =>{
console.log(n);
for(i = 0; i < n; i++)
blocks.push(queryBlock(i));
Promise.all(blocks).then((value)=>{
res.end(JSON.stringify(value));
});
});
});
server.listen(8080, () => {
console.log('alhamdulillah');
});
también podrías hacer:
const latest = await web3.eth.getBlockNumber()
const blockNumbers = _range(latest - n, latest + 1, 1);
const blocks = await Promise.all(blockNumbers.map(n => provider.eth.getBlock(n)));
y luego proceda a deconstruir la información del bloque de la matriz de bloques. Descubrí que usar Promise.all es mucho más rápido y fácil de administrar.
¿Por qué solo 10? Puede obtener la información más reciente de N bloques con este código NodeJS:
const Web3 = require("web3")
const web3 = new Web3("https://rpc-provider.........")
async function GetLastNBlocks(n) {
latestBlock=await web3.eth.getBlockNumber()
for (let i = 0; i < n; i++) {
web3.eth.getBlock(latestBlock-i).then((err,data)=>{
console.log(latestBlock-i,data,err,"\n")
})
}
}
GetLastNBlocks(10)
nota : no olvide cambiar RPC-Provider link
en la segunda línea de código anterior.
Lista de proveedores de RPC de diferentes blockchains https://github.com/arddluma/awesome-list-rpc-nodes-providers
DOCUMENTOS DE REFERENCIA https://web3js.readthedocs.io/en/v1.7.3/web3-eth.html#
GruesoMiddleManager