¿Cómo obtener transacciones por cuenta usando web3 js?

Estoy seguro de que esta pregunta se hizo antes, pero no encontré ningún resultado que ayudara a mi problema.

¿Cómo puedo obtener las transacciones (entradas y salidas) de una cuenta determinada? Yo uso nodejs y web3?

Con esta línea obtengo el número de transacciones enviadas:

web3.eth.getTransactionCount(accounts[i])

Entonces, al menos web3 debería saber algo sobre la actividad de la cuenta.

¿Hay alguna manera fácil de obtener las transacciones de mis cuentas? ¿O me perdí algo al respecto? ¿Tengo que rastrear toda la cadena de bloques, bloque por bloque, para obtener mis transacciones?

En realidad, hay una distinción importante entre conocer la cantidad de transacciones y obtener esos txs. El "recuento de transacciones" también es el nonce de la cuenta, que se necesita para crear nuevas transacciones y es parte del estado de la cuenta, al igual que el saldo. Las transacciones anteriores no son parte del estado actual, por lo que debe filtrar todos los bloques anteriores para encontrarlos.
Tengo el mismo problema. ¿Alguien tiene un fragmento de código de Java, usando web3j? Gracias
La mejor respuesta podría ser la siguiente: ethereum.stackexchange.com/a/86426/55270

Respuestas (8)

Las transacciones simples no están indexadas. Por lo tanto, debe iterar sobre todos los bloques, usar algún tipo de índice fuera de la cadena (por ejemplo , etherscan.io ), o crear uno usted mismo y usarlo.

Por ejemplo, puede usar este enfoque heurístico sin tener que procesar toda la cadena

var myAddr = '0xbb9bc244d798123fde783fcc1c72d3bb8c189413';
var currentBlock = eth.blockNumber;
var n = eth.getTransactionCount(myAddr, currentBlock);
var bal = eth.getBalance(myAddr, currentBlock);
for (var i=currentBlock; i >= 0 && (n > 0 || bal > 0); --i) {
    try {
        var block = eth.getBlock(i, true);
        if (block && block.transactions) {
            block.transactions.forEach(function(e) {
                if (myAddr == e.from) {
                    if (e.from != e.to)
                        bal = bal.plus(e.value);
                    console.log(i, e.from, e.to, e.value.toString(10));
                    --n;
                }
                if (myAddr == e.to) {
                    if (e.from != e.to)
                        bal = bal.minus(e.value);
                    console.log(i, e.from, e.to, e.value.toString(10));
                }
            });
        }
    } catch (e) { console.error("Error in block " + i, e); }
}

¿Como funciona?

Usando la información disponible sobre el estado actual (número de transacciones "desde" y el saldo actual), retrocede en el tiempo hasta que se hayan encontrado al menos tantas transacciones "desde", y luego continúa retrocediendo hasta que el saldo llega a 0.

La limitación inherente es que no se encontrarán las transacciones de valor 0 antes de que se financiara la cuenta.


Los eventos de contrato , por otro lado, están indexados. Entonces, si está desarrollando un contrato inteligente, puede hacer uso de eso.
Usando la API web3 1.0.0:

web3.eth.getPastLogs({fromBlock:'0x0',address:'0x9e3319636e2126e3c0bc9e3134AEC5e1508A46c7'})
.then(res => {
  res.forEach(rec => {
    console.log(rec.blockNumber, rec.transactionHash, rec.topics);
  });
}).catch(err => console.log("getPastLogs failed", err));

O a través de JSON RPC eth_getLogs .

Este guión tiene un getTransactionsByAccount. Debe modificarlo anteponiendo web3, por ejemplo, use web3.eth.blockNumberen lugar de solo eth.blockNumber(que funciona en la consola Geth ya que la consola Geth incluye el objeto web3).

Arriba le dará las transacciones fáciles, y se necesitará más trabajo para Cómo obtener transacciones internas de contrato .

Además del comentario de @Tjaden, web3.eth.getTransactionCount(account)solo proporciona la cantidad de transacciones que se originan en account.

Gracias. Antes de preguntar, encontré el guión y lo pegué en mi editor. No funcionó y esperaba que hubiera una manera fácil de encontrar por qué. No hay tiempo para probar ahora, pero ¿se hace cuando agrego web3 o tengo que definir variables, etc.?
web3debe ser el único objeto que necesita; las otras variables se pasan a la getTransactionsByAccountfunción.
Si está ejecutando el script en el nodo, debe esperar cada llamada web3
¿Esto también devuelve las transacciones pendientes?
La mejor respuesta en mi opinión debido a su practicidad. Lástima que para bscscan esto no sea práctico, porque a veces parecen retrasarse mucho.

La respuesta adecuada a la fecha:

class TransactionChecker {
    constructor(address) {
        this.address = address.toLowerCase();
        this.web3 = new Web3("https://mainnet.infura.io/v3/60968ff3b2f84a0ebdff7a993f4d080b");
}

async checkBlock() {
    let block = await this.web3.eth.getBlock('latest');
    let number = block.number;
    let transactions = block.transactions;
    //console.log('Search Block: ' + transactions);

    if (block != null && block.transactions != null) {
        for (let txHash of block.transactions) {
            let tx = await this.web3.eth.getTransaction(txHash);
            if (this.address == tx.to.toLowerCase()) {
                console.log("from: " + tx.from.toLowerCase() + " to: " + tx.to.toLowerCase() + " value: " + tx.value);
            }
        }
    }
  }
}

 var transactionChecker = new  TransactionChecker('0x69fb2a80542721682bfe8daa8fee847cddd1a267');
 transactionChecker.checkBlock();

Producción:

 from: 0x240946ca5418ba362e9011d6454ff858adc0e0ae to: 0x2c334d73c68bbc45dd55b13c5dea3a8f84ea053c value: 2000000000000000000
 from: 0x410282b6e53c0d48007ace4874b6afa6754425f7 to: 0xe6c46e42256703de29e37b01a246e11a5b102c6b value: 450000000000000000
 from: 0xffc5e446d5f32f7c8479b5eae4271751dacd45b8 to: 0x7a250d5630b4cf539739df2c5dacb4c659f2488d value: 1000000000000000000
 from: 0xd8376d071c27582fb15c6a9a46eaf23e6adaf76e to: 0x7a250d5630b4cf539739df2c5dacb4c659f2488d value: 2000000000000000000
 from: 0x7f5896c91a1bf9e94d4d81b142daa61d50c8eecb to: 0xba2eac592746fc7427247b591507dac51c51a500 value: 0
 from: 0x02314d41f62e62c02b8cbd036334573db1334f11 to: 0x4d62c46898bdcd6b14118646ed1401336c9a47b3 value: 0
 from: 0x9cc53c6f67332f7c4aa5a56f83121e51d30c5923 to: 0x0a331b3de09c986eaaf967d8b493b816cb7902e8 value: 296699999999999940
 from: 0xc09e7e05da6b021d881b0e3ec580307c40102e2d to: 0xaf4afb03963f3f5f87a3e20a0f9191270c7b3436 value: 638368162441200000
 from: 0x32be343b94f860124dc4fee278fdcbd38c102d88 to: 0xa910f92acdaf488fa6ef02174fb86208ad7722ba value: 1487418725338565767
 from: 0x343b18bf65d9d2a64bb763246e207d2d303328bf to: 0xdac17f958d2ee523a2206206994597c13d831ec7 value: 0
 from: 0x343b18bf65d9d2a64bb763246e207d2d303328bf to: 0xdac17f958d2ee523a2206206994597c13d831ec7 value: 0
 from: 0xcb0249c85ba9b6e32d79adaae2f9660ae0dfbefc to: 0x239220734954c95c852f0fc059ec783a3f0e283c value: 1000000000000000
¿Esto también funciona con transacciones pendientes?

Sé que es demasiado tarde para responder a esta pregunta. Pero espero que pueda ayudar a otros.

No puede listar transacciones directamente usando web3 y JSON-RPC. Para tener una lista de transacciones que involucran una dirección, debe escanear bloques completos (o una parte) de la cadena de bloques de Ethereum para encontrarlos.

¡Podrías adivinar! ¡Es bastante intensivo en tiempo!

Para resolver este problema, necesita un indexador de bloques o un explorador de bloques. Indexan todos los datos de blockchain en diferentes formas y órdenes. Utiliza un explorador de bloques como "Etherscan" o implementa un indexador de código abierto como "Blockscout".

Le brindan una API más útil (en comparación con ETH RPC). Debe interactuar con el método "txlist" en el módulo "cuenta".

Esto no es correcto. No tiene la capacidad de obtener transacciones de una dirección directamente , pero puede listar la transacción usando web3 y JSON-RPC. Solo necesitarás un poco de lógica para filtrarlos.

No encontré este método 'web3.eth.getTransactionsByAccount' en mi consola. como veo, no hay una forma directa de obtener transacciones por dirección de cuenta, tal vez debería rastrear toda la cadena de bloques a su manera o puede usar una API de terceros.

Ese método no existe en web3. A lo que se refería @eth era a un script llamado getTransactionsByAccount.
 web3.eth.getTransactionCount("0x8fFcABE2D92A76286b58f6C286980877C3C2C5C6")
 .then((b=console.log)=>{
    console.log(b)
    for(var i=0;i<b;i++){
            web3.eth.getBlock(b-i).then((Block)=>
            {

            a =[
                            Block.hash
                 ]
                     console.log(a);
                 var  iterator =a.values()
                 for (let elements of iterator) { 
             web3.eth.getTransactionFromBlock(elements).then(console.log)


                } 
             });
         }
         });
¿Esto también funciona con transacciones pendientes?