ethers.js icon indicating copy to clipboard operation
ethers.js copied to clipboard

Missing r when I was trying to get transactions from block

Open yarikMyroniuk opened this issue 1 year ago • 16 comments

Ethers Version

6.7.1

Search Terms

I saw the same issue but about missing v

Describe the Problem

I have the same issue but about missing r instead of missing v but only with zkSyncEra

But If I use method getTransaction(hash), I don't receive any errors

version lib: "ethers": "^6.7.1",

UPD: I was trying to do this with latest version ethers 6.11.1

Code Snippet

I was trying to get prefetchedTransactions from block, using method getBlock(block, true)

Contract ABI

No response

Errors

TypeError: missing r (argument="signature", value={ "blockHash": "0xea2f9049921549a11590a77ae13305f83640783b90da382b2446be23db85aaa6", "blockNumber": "0x1af3974", "chainId": "0x144", "from": "0xef1e151d145c49a2c776cade6443b47d71abe441", "gas": "0x60f97", "gasPrice": "0x75ec5cb6", "hash": "0x53e4a8dbd46b3d3604a19d4b007fe9410e94c75b3c17c0d6f0f50f1ef0bf5855", "input": "0x", "l1BatchNumber": "0x6f853", "l1BatchTxIndex": "0x517", "maxFeePerGas": "0x75ec5cb6", "maxPriorityFeePerGas": "0x0", "nonce": "0x0", "to": "0xef1e151d145c49a2c776cade6443b47d71abe441", "transactionIndex": "0x3", "type": "0xff", "value": "0x55db9421dba88956" }, code=INVALID_ARGUMENT, version=6.11.1)

Environment

node.js (v12 or newer)

Environment (Other)

No response

yarikMyroniuk avatar Mar 06 '24 08:03 yarikMyroniuk

@yarikMyroniuk You can try out this code to retrieve all transactions from the latest block

Ethers.js :


const { ethers } = require('ethers');

// set privider
const provider = new ethers.providers.JsonRpcProvider('https://eth-mainnet.g.alchemy.com/v2/UvV96RRoOF8HQ44Tn_bm7FaAuwcxct2x',);

// Get the latest block number
provider.getBlockNumber().then((blockNumber) => {
    // Get the details of the latest block
    provider.getBlock(blockNumber).then((block) => {
        console.log('Block Number:', block.number);
        console.log('Hash:', block.hash);

        // get all tx from latest block using loop
        if (block.transactions.length > 0) {
          block.transactions.forEach((txHash) => {
            // Get transaction details
            provider.getTransaction(txHash).then((tx) => {
              console.log('Transaction Hash:', tx.hash);
              console.log('From:', tx.from);
              console.log('To:', tx.to);
              console.log('Value:', ethers.utils.formatEther(tx.value), 'ETH');
              console.log('---------------------------');
            });
          });
        }
      })
      .catch((err) => {
        console.error('Error fetching block details:', err);
      });
  })
  .catch((err) => {
    console.error('Error fetching latest block number:', err);
  });

If you want all transaction details from a specific block, just change the 'blockNumber' value to your desired block number, then run the code to get all the transactions.

Ethers.js :

const { ethers } = require('ethers');

// set privider
const provider = new ethers.providers.JsonRpcProvider('https://eth-mainnet.g.alchemy.com/v2/UvV96RRoOF8HQ44Tn_bm7FaAuwcxct2x',);

let blockNumber = 19489042; // you block number
provider.getBlock(blockNumber).then((block) => {
    console.log('Block Number:', block.number);
    console.log('Hash:', block.hash);

    // get all tx from latest block using loop
    if (block.transactions.length > 0) {
      block.transactions.forEach((txHash) => {
        // Get transaction details
        provider.getTransaction(txHash).then((tx) => {
          console.log('Transaction Hash:', tx.hash);
          console.log('From:', tx.from);
          console.log('To:', tx.to);
          console.log('Value:', ethers.utils.formatEther(tx.value), 'ETH');
          console.log('---------------------------');
        });
      });
    }
  })
.catch((err) => {
  console.error('Error fetching block details:', err);
});
  

adamsaho avatar Mar 22 '24 08:03 adamsaho

@mahatotarit Yeah, You are right, I have already done this implementation but for every tx I will need to call method getTransaction that makes some load on the RPC and increases the amount of requests

I wanted to do without method getTransaction by hash

yarikMyroniuk avatar Mar 22 '24 10:03 yarikMyroniuk

Could you please explain exactly what you want in detail ? I'm here to help with your work.

adamsaho avatar Mar 23 '24 08:03 adamsaho

@mahatotarit Yeah, I need to receive all transactions, by type prefetchedTransactions and not call the method for obtaining a transaction by hash one by one, since this requires a request in rpc and so I need to receive all transactions with one request

yarikMyroniuk avatar Mar 28 '24 20:03 yarikMyroniuk

Can you provide example ?

adamsaho avatar Mar 29 '24 11:03 adamsaho

@mahatotarit

You sent example with this code

if (block.transactions.length > 0) {
  block.transactions.forEach((txHash) => {
    // Get transaction details
    provider.getTransaction(txHash).then((tx) => {
      console.log('Transaction Hash:', tx.hash);
      console.log('From:', tx.from);
      console.log('To:', tx.to);
      console.log('Value:', ethers.utils.formatEther(tx.value), 'ETH');
      console.log('---------------------------');
    });
  });
}

I don't like this implementation because in this case I need to fetch each transaction separately, which leads to additional requests

but this method has a better alternative like getBlock(block, true) which already has transactions in field "prefetchedTransactions", but with zkSync and with zkLinkNova, it doesn't work because I received this error: "TypeError: missing r (argument="signature", value={ "blockHash": "0xea2f9049921549a11590a77ae13305f83640783b90da382b2446be23db85aaa6", "blockNumber": "0x1af3974", "chainId": "0x144", "from": "0xef1e151d145c49a2c776cade6443b47d71abe441", "gas": "0x60f97", "gasPrice": "0x75ec5cb6", "hash": "0x53e4a8dbd46b3d3604a19d4b007fe9410e94c75b3c17c0d6f0f50f1ef0bf5855", "input": "0x", "l1BatchNumber": "0x6f853", "l1BatchTxIndex": "0x517", "maxFeePerGas": "0x75ec5cb6", "maxPriorityFeePerGas": "0x0", "nonce": "0x0", "to": "0xef1e151d145c49a2c776cade6443b47d71abe441", "transactionIndex": "0x3", "type": "0xff", "value": "0x55db9421dba88956" }, code=INVALID_ARGUMENT, version=6.11.1)"

yarikMyroniuk avatar Apr 04 '24 12:04 yarikMyroniuk

@mahatotarit Hey, What about my issue?

yarikMyroniuk avatar Apr 18 '24 08:04 yarikMyroniuk

Same error now after successful transaction on Gnosis. 100% reproducible on our projects.

egorFiNE avatar Apr 22 '24 13:04 egorFiNE

@yarikMyroniuk

Please provide your full code.

adamsaho avatar Apr 22 '24 13:04 adamsaho

Seems reliably reproducible by me on gnosis chain on different wallets (Metamask and Rabby)

egorFiNE avatar Apr 24 '24 08:04 egorFiNE

It looks like they are using a custom type 0xff. Any info on documentation on their transaction format? It doesn't seem to be an Ethereum compatible format, so likely will need a custom plug-in.

ricmoo avatar Apr 24 '24 12:04 ricmoo

@ricmoo Yeah, I use the native method from rpc without any library, it looks like it's working

yarikMyroniuk avatar Apr 25 '24 09:04 yarikMyroniuk

@ricmoo Gnosis doesn't use any non-standard type but the bug is repeatable about 70% of the time. If you could point me out where to start debugging - I'd love to dive in.

egorFiNE avatar Apr 25 '24 10:04 egorFiNE

@ricmoo Gnosis doesn't use any non-standard type but the bug is repeatable about 70% of the time. If you could point me out where to start debugging - I'd love to dive in.

@egorFiNE @ricmoo I also encountered this issue. It appears when upgrading ethers to version 6 or above, but it does not occur in version 5.4.6. Additionally, when I set a breakpoint, the issue disappears, which is quite strange.

So, should ethers 6 consider compatibility for cases where r, s, and v are not returned? Or, how should developers modify their code to avoid this bug?

307590317 avatar Feb 10 '25 02:02 307590317

Same issue here.

Ethers v5 might indeed be working but its skipping transactions. Ethers v6 throws the missing "r" error from the sig.

Its really easy to reproduce.

Just call getBlock(block_number, true) on any zksync chain, like Abstract for example.

kakashigr avatar May 10 '25 20:05 kakashigr

Does it happen consistently with the same transaction hashes? Or is it intermittent? How about if you use different providers?

This is a big (I believe) in the node itself, returning invalid data. What node software are you using (Geth, Parity, etc)?

I’m planning for looser matching in the figure which will solve these issues (so long as you don’t rely on r in this case for example).

ricmoo avatar May 11 '25 15:05 ricmoo