¿Cómo puedo obtener los datos de los últimos 10 bloques a través de web3.js?

¿Cómo puedo obtener los últimos 10 datos de bloques usando web3.js como lo hace la mayoría de los exploradores de bloques?

Respuestas (6)

Hay algunos problemas con la respuesta aceptada:

  1. como menciona @Lam-Le, .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.
  2. el bucle crea una cantidad desproporcionada de solicitudes de red (2 x i+1).

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 requestmé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()
Su enlace a BatchRequests ahora es 404.

Usar web3.eth.getBlockconweb3.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 )

debe almacenarse en caché web3.eth.blockNumberen la variable local antes de hacer un bucle en caso de que llegue un nuevo bloque
Si aparece un nuevo bloque, también se puede desear más lógica porque los datos ya no son los "más recientes". Pero votado a favor, buen punto de @LamLe.
getBlock es asíncrono, debe poner eso en la función asíncrona antes de ponerlo en console.log
@Rafid gracias, actualicé con un ejemplo para web3.js 1.0+

Existe 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.theny 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 linken 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#