<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Eugene Aseev</title>
    <description>The latest articles on DEV Community by Eugene Aseev (@easeev).</description>
    <link>https://dev.to/easeev</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F546251%2F702c3b00-f216-409a-8600-f5a64c3816d7.jpeg</url>
      <title>DEV Community: Eugene Aseev</title>
      <link>https://dev.to/easeev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/easeev"/>
    <language>en</language>
    <item>
      <title>The ultimate guide to getting multiple token balances on Ethereum</title>
      <dc:creator>Eugene Aseev</dc:creator>
      <pubDate>Mon, 18 Jan 2021 09:22:06 +0000</pubDate>
      <link>https://dev.to/easeev/the-ultimate-guide-to-getting-multiple-token-balances-on-ethereum-21a3</link>
      <guid>https://dev.to/easeev/the-ultimate-guide-to-getting-multiple-token-balances-on-ethereum-21a3</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;One of the coolest things about Ethereum is its decentralized nature—all of its transactions since the genesis block can be publicly accessible by anyone. But with an average of one million transactions a day, it can be challenging to filter out the data you need fast and efficiently.&lt;/p&gt;

&lt;p&gt;This post focuses on one particular task—retrieving token balances of an address on Ethereum.&lt;/p&gt;

&lt;p&gt;The challenge with this task is that there is a significant difference in how ether is stored on an address and how the tokens are stored. Ether is the balance of an address, while tokens are the balance of a contract attributed to an address.&lt;/p&gt;

&lt;p&gt;To get the ether balance of a wallet address, you need to watch the address.&lt;/p&gt;

&lt;p&gt;To get the token balance of the same wallet address, you need to watch the list of token contract addresses you want to track. This process requires the execution of not one but multiple JSON-RPC requests consistently—it's time consuming and resource wasteful if executed individually.&lt;/p&gt;

&lt;p&gt;At the time of writing this post, it was quite a challenge to find a good guide on how to retrieve data from the ledger in batches. Hence, I've decided to write one. Together, in this post, we will go through three different approaches on how to retrieve token balances via the ERC-20 &lt;code&gt;balanceOf&lt;/code&gt; contract ABI function in batches from the Ethereum ledger.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;a href="https://graphql.org/" rel="noopener noreferrer"&gt;GraphQL&lt;/a&gt; — alternative to the Ethereum JSON-RPC interface introduced in &lt;a href="https://eips.ethereum.org/EIPS/eip-1767" rel="noopener noreferrer"&gt;EIP 1767&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt; &lt;a href="https://github.com/pooltogether/etherplex" rel="noopener noreferrer"&gt;Etherplex&lt;/a&gt; — a JavaScript library that makes use of the &lt;a href="https://github.com/makerdao/multicall" rel="noopener noreferrer"&gt;multicall&lt;/a&gt; smart contract to aggregate function calls and executes them in batch.&lt;/li&gt;
&lt;li&gt; &lt;a href="https://web3js.readthedocs.io/en/v1.2.0/web3-eth.html#batchrequest" rel="noopener noreferrer"&gt;web3.js BatchRequest&lt;/a&gt; — the web3.js batch method that aggregates the list of contract function calls and converts them into an array of JSON-RPC calls before sending it to the Ethereum node in one XMLHttpRequest.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Before you start, we assume that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You already know how to write code — preferably JavaScript.&lt;/li&gt;
&lt;li&gt;You have the code samples cloned and your environment set up. See the &lt;a href="https://github.com/chainstack/ethereum-token-balances" rel="noopener noreferrer"&gt;repository&lt;/a&gt; prepared for this post.&lt;/li&gt;
&lt;li&gt;You already have your Ethereum node endpoint. If you don't, you can spin up your node with us on &lt;a href="https://chainstack.com/pricing/" rel="noopener noreferrer"&gt;Chainstack&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Helper functions
&lt;/h3&gt;

&lt;p&gt;Before we deep-dive into sample code, let's take a look at the two helper functions we will be using across the three different approaches.&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;getTokens()&lt;/code&gt;, we dynamically fetch a list of token address, symbol, and decimals from &lt;a href="https://tokenlists.org/" rel="noopener noreferrer"&gt;Token Lists&lt;/a&gt;—a community-led initiative to improve discoverability and trust in ERC-20 token lists. You can replace &lt;code&gt;tokenSource&lt;/code&gt; with an API endpoint of your choice or hardcode a list of tokens within this function. In our example, we will be using the &lt;a href="https://tokenlists.org/token-list?url=https://tokens.coingecko.com/uniswap/all.json" rel="noopener noreferrer"&gt;CoinGecko&lt;/a&gt; list.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;require('isomorphic-fetch');

const tokenSource = 'https://tokens.coingecko.com/uniswap/all.json';
const getTokens = () =&amp;gt; {
  return fetch(tokenSource, {
    methods: 'GET',
    headers: { 'Content-Type': 'application/json', },
  }).then(data =&amp;gt; data.json());
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In &lt;code&gt;convertToNumber()&lt;/code&gt;, we convert the hexadecimal response to a readable numeric format.&lt;/p&gt;

&lt;p&gt;Note that we must avoid dividing tokens that have 0 balance with more than 20 decimals as this exceeds the BigNumber minimum limit and will result in an error.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const Web3 = require('web3');

const convertToNumber = (hex, decimals) =&amp;gt; {
  const balance = Web3.utils.toBN(hex);
  let balanceDecimal = balance;
  if (decimals &amp;amp;&amp;amp; (balance.toLocaleString() === '0' &amp;amp;&amp;amp; decimals &amp;lt; 20)) {
    balanceDecimal = balance.div(Web3.utils.toBN(10 ** decimals));
  }

  return balanceDecimal.toLocaleString();
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Constants
&lt;/h3&gt;

&lt;p&gt;In the &lt;code&gt;constant.js&lt;/code&gt; file, we store the constants we will be using for our queries. Remember to update the constants before executing the scripts.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;ABI&lt;/code&gt; — contract ABI with only the &lt;code&gt;balanceOf&lt;/code&gt; function. Remember to add the function calls you are planning to execute to the ABI constant.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;username&lt;/code&gt; — your Ethereum node RPC username.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;password&lt;/code&gt; — your Ethereum node RPC password.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;rpcEndpoint&lt;/code&gt; — your Ethereum node RPC endpoint.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;bathEndpoint&lt;/code&gt; — your Ethereum node RPC endpoint with authentication credentials.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const abi = [
  {
    constant: true,
    inputs: [
      {
        name: '_owner',
        type: 'address',
      },
    ],
    name: 'balanceOf',
    outputs: [
      {
        name: 'balance',
        type: 'uint256',
      },
    ],
    payable: false,
    stateMutability: 'view',
    type: 'function',
  },
];
// replace with your Ethereum node RPC username
const username = 'username';
// replace with your Ethereum node RPC password
const password = 'password';
// replace with your Ethereum node RPC endpoint
const rpcEndpoint = 'https://nd-123-456-789.p2pify.com';
// replace with your Ethereum node RPC endpoint
const bathEndpoint = `https://${username}:${password}@nd-123-456-789.p2pify.com`;
// replace with the address you want to query
const walletAddress = '0x3f5ce5fbfe3e9af3971dd833d26ba9b5c936f0be';

module.exports = {
  abi,
  bathEndpoint,
  password,
  rpcEndpoint,
  username,
  walletAddress,
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  GraphQL
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://graphql.org/" rel="noopener noreferrer"&gt;GraphQL&lt;/a&gt; is a query language designed to provide flexibility, giving client control over the format of the data anyone wants. This solves one of the most common issues people face when reading data from the Ethereum ledger—underfetching and overfetching data. This can impact your day-to-day operation, especially for users querying data from multiple contracts and different block height. &lt;a href="https://chainstack.com/graphql-on-ethereum-availability-on-chainstack-and-a-quick-rundown/" rel="noopener noreferrer"&gt;GraphQL API&lt;/a&gt; is available on all dedicated Ethereum nodes on Chainstack.&lt;/p&gt;

&lt;p&gt;Let us take a look at the example below on how we go about retrieving &lt;a href="https://tokenlists.org/token-list?url=https://tokens.coingecko.com/uniswap/all.json" rel="noopener noreferrer"&gt;CoinGeсko&lt;/a&gt; list token balances using GraphQL.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;require('isomorphic-fetch');
const ethers = require('ethers');
const { abi, bathEndpoint, walletAddress } = require('./constant.js');
const { convertToNumber, getTokens } = require('./utils');

const convertIndexToAlphetString = number =&amp;gt; number
  .toString()
  .split('')
  .map(numberChar =&amp;gt; String.fromCharCode(65 + parseInt(numberChar)))
  .join('');

const queryTemplate = (index, { address }, callData) =&amp;gt; `
  ${convertIndexToAlphetString(index)}: call(data: { to: "${address}", data: "${callData}" }) { data }`;

const retrieveTokenBalanceViaGraphQL = (tokens) =&amp;gt; {
  const ethersInterface = new ethers.utils.Interface(abi);
  const callData = ethersInterface
    .functions.balanceOf.encode([walletAddress]);
  const query = tokens.map((token, index) =&amp;gt; {
    return queryTemplate(index, token, callData);
  }).join('\n');

  return fetch(`${bathEndpoint}/graphql`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ query: `{ block { ${query} } }` }),
  })
    .then(data =&amp;gt; data.json());
};

const main = async () =&amp;gt; {
  const { tokens } = await getTokens();

  const tokenBalances = await retrieveTokenBalanceViaGraphQL(tokens)
    .then(({ data: { block: balances } })  =&amp;gt; {
      const output = {};

      Object.entries(balances).map(([, { data: hex }], index) =&amp;gt; {
        const { name, decimals, symbol } = tokens[index];

        output[name] = `${convertToNumber(hex, decimals)} ${symbol}`;
      });

      return output;
    });

  console.log(tokenBalances);
};

main();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we dynamically generate the query from the list of tokens before sending it to our GraphQL API endpoint. This approach took an average of &lt;strong&gt;2289ms&lt;/strong&gt; out of 10 runs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pros of GraphQL
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Streamlines complex processes
&lt;/h4&gt;

&lt;p&gt;Depending on the use case, you can easily combine queries on different contract function calls, different contract addresses for different wallet addresses at different block heights into one GraphQL query.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;query {
  ChainLinkToken11404479: block(number: 11404479) {
    call(data: { to: "0x514910771AF9Ca656af840dff83E8264EcF986CA", data: "0x70a082310000000000000000000000003f5ce5fbfe3e9af3971dd833d26ba9b5c936f0be" }) {
      data
    }
  }

  ChainLinkTokenLatest: block {
    call(data: { to: "0x514910771AF9Ca656af840dff83E8264EcF986CA", data: "0x70a082310000000000000000000000003f5ce5fbfe3e9af3971dd833d26ba9b5c936f0be" }) {
      data
    }
  }

  DaiStablecoin11404470: block(number: 11404470) {
    call(data: { to: "0x6B175474E89094C44Da98b954EedeAC495271d0F", data: "0x70a0823100000000000000000000000046340b20830761efd32832a74d7169b29feb9758" }) {
      data
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Will yield:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
{
  "data": {
    "ChainLinkToken11404479": {
      "call": {
        "data": "0x00000000000000000000000000000000000000000003a53a9199924822b36355"
      }
    },
    "ChainLinkTokenLatest": {
      "call": {
        "data": "0x00000000000000000000000000000000000000000003a571b23d1cfe6e4e6355"
      }
    },
    "DaiStablecoin11404470": {
      "call": {
        "data": "0x0000000000000000000000000000000000000000000024e132e65f0c1c62ddeb"
      }
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Through &lt;a href="https://graphql.org/learn/queries/#aliases" rel="noopener noreferrer"&gt;GraphQL alias&lt;/a&gt;, we can efficiently aggregate multiple RPC calls for different data into one GraphQL query and let Geth and GraphQL do the heavy lifting behind the scenes.&lt;/p&gt;

&lt;h4&gt;
  
  
  Not reliant on dependencies
&lt;/h4&gt;

&lt;p&gt;There are no additional libraries required to use GraphQL. This means that your code will be more stable and less vulnerable to security loopholes or outdated dependencies.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cons of GraphQL
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Function calls must be encoded
&lt;/h4&gt;

&lt;p&gt;Executing function calls through GraphQL works the same way as a normal RPC call, which means function calls must be encoded manually and passed onto the query. This might make the code confusing to read.&lt;/p&gt;

&lt;h4&gt;
  
  
  GraphQL alias has strict format requirements
&lt;/h4&gt;

&lt;p&gt;According to the &lt;a href="http://spec.graphql.org/June2018/#sec-Names" rel="noopener noreferrer"&gt;GraphQL specification&lt;/a&gt;, names must strictly follow the following regex pattern: &lt;code&gt;/[_A-Za-z][_0-9A-Za-z]*/&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This makes it difficult to use symbols or contract names as the alias since some contract names or symbols do not match this regex pattern. In the example above, we work around this constraint via the &lt;code&gt;convertIndexToAlphetString()&lt;/code&gt; function which generates a unique alphabetical identifier based on the index of the token in the list, which, in turn, we later map to the token list using the same index.&lt;/p&gt;

&lt;h2&gt;
  
  
  Etherplex
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/pooltogether/etherplex" rel="noopener noreferrer"&gt;Etherplex&lt;/a&gt; is a library that consolidates the list of the &lt;a href="https://github.com/ethers-io/ethers.js/" rel="noopener noreferrer"&gt;ethers.js&lt;/a&gt; contract function calls into one JSON-RPC call on the &lt;a href="https://github.com/makerdao/multicall" rel="noopener noreferrer"&gt;multicall&lt;/a&gt; smart contract aggregate function, which iterates and executes the list of contract function calls.&lt;/p&gt;

&lt;p&gt;Below is the implementation of the aggregate function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function aggregate(Call[] memory calls) public returns (uint256 blockNumber, bytes[] memory returnData) {
  blockNumber = block.number;
  returnData = new bytes[](calls.length);

  for(uint256 i = 0; i &amp;lt; calls.length; i++) {
    (bool success, bytes memory ret) = calls[i].target.call(calls[i].callData);
    require(success);

    returnData[i] = ret;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let us look at the example below on how we go about retrieving &lt;a href="https://tokenlists.org/token-list?url=https://tokens.coingecko.com/uniswap/all.json" rel="noopener noreferrer"&gt;CoinGecko&lt;/a&gt; token list balances using Etherplex.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const { ethers } = require('ethers');
const { batch, contract } = require('@pooltogether/etherplex');
const { abi, username, password, rpcEndpoint, walletAddress } = require('./constant.js');
const { convertToNumber, getTokens } = require('./utils');

const provider = new ethers.providers.JsonRpcProvider({
  url: rpcEndpoint,
  user: username,
  password: password,
});

const generateContractFunctionList = tokens =&amp;gt;
  tokens.map(({ address: tokenAddress, symbol }) =&amp;gt;
    contract(symbol, abi, tokenAddress).balanceOf(walletAddress),
  );

const main = async () =&amp;gt; {
  const { tokens } = await getTokens();
  const start = new Date().getTime();
  const args = generateContractFunctionList(tokens);
  const tokenBalances = await batch.apply(null, [provider, ...args])
    .then(balances =&amp;gt; {
      const output = {};

      Object.entries(balances).map(([symbol, { balanceOf }], index) =&amp;gt; {
        const balance = convertToNumber(balanceOf[0]._hex, tokens[index].decimals);

        output[tokens[index].name] = `${balance} ${symbol}`;
      });

      return output;
    });

  console.log(tokenBalances);
};

main();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we dynamically generate the list of &lt;code&gt;balanceOf&lt;/code&gt; function calls from the list of tokens before passing it to Ethereplex's batch function. This approach took an average of &lt;strong&gt;3815ms&lt;/strong&gt; out of 10 runs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pros of Etherplex
&lt;/h3&gt;

&lt;h4&gt;
  
  
  More human readable code
&lt;/h4&gt;

&lt;p&gt;Unlike GraphQL, Ethereplex works on top of ethers.js, which allows us to use the contract's ABI function name instead of encoding them, which makes the code more human-readable.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cons of Etherplex
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Reliant on Etherplex library
&lt;/h4&gt;

&lt;p&gt;At the time of this post, Etherplex has not integrated support for the ethers.js &lt;a href="https://docs.ethers.io/v5/api/providers/provider/#Provider--transaction-methods" rel="noopener noreferrer"&gt;blockTag functionality&lt;/a&gt;, which allows the user to run a query on different blocks. If this is a requirement for you, I suggest you consider:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Contributing to the Etherplex library.&lt;/li&gt;
&lt;li&gt;Implementing your own wrapper using the &lt;a href="https://github.com/makerdao/multicall" rel="noopener noreferrer"&gt;multicall&lt;/a&gt; smart contract.&lt;/li&gt;
&lt;li&gt;Using other approaches described in this post.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Unstable
&lt;/h4&gt;

&lt;p&gt;The multicall smart contract can sometimes be unavailable and the process will fall back to using the native JSON-RPC approach. For larger queries, this will result in a timeout error: &lt;code&gt;Error: execution aborted (timeout = 5s)&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  web3.js BatchRequest
&lt;/h4&gt;

&lt;p&gt;The web3.js &lt;code&gt;BatchRequest&lt;/code&gt; method aggregates the list of contract function calls and converts them into an array of JSON-RPC calls before sending it to the Ethereum node in one XMLHttpRequest. The Ethereum node will process these JSON-RPC requests asynchronously before sending them back to the client.&lt;/p&gt;

&lt;p&gt;Let us look at the example below on how we go about retrieving &lt;a href="https://tokenlists.org/token-list?url=https://tokens.coingecko.com/uniswap/all.json" rel="noopener noreferrer"&gt;CoinGecko&lt;/a&gt; token list balances using the &lt;code&gt;BatchRequest&lt;/code&gt; method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const Web3 = require('web3');
const { convertToNumber, getTokens } = require('./utils');
const { abi, bathEndpoint, walletAddress } = require('./constant.js');

const web3 = new Web3(new Web3.providers.HttpProvider(bathEndpoint));

const generateContractFunctionList = ({ tokens, blockNumber }) =&amp;gt; {
  const batch = new web3.BatchRequest();

  tokens.map(async ({ address: tokenAddress, symbol, decimals }) =&amp;gt; {
    const contract = new web3.eth.Contract(abi);
    contract.options.address = tokenAddress;

    batch.add(
      contract.methods.balanceOf(walletAddress).call.request({}, blockNumber),
    );
  });

  return batch;
};

const main = async () =&amp;gt; {
  const { tokens } = await getTokens();

  const batch = generateContractFunctionList({ tokens });
  const tokenBalances = {};
  const { response } = await batch.execute();
  response.forEach(({ _hex }, index) =&amp;gt; {
    const { name, decimals, symbol } = tokens[index];

    tokenBalances[name] = `${convertToNumber(_hex, decimals)} ${symbol}`;
  });

  console.log(tokenBalances);
};

main();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we add the list of &lt;code&gt;balanceOf&lt;/code&gt; contract function calls from the list of tokens before calling the &lt;code&gt;batch.execute&lt;/code&gt; function. Note that the performance for the batch command may vary depending on the RPC endpoint provider you're using—&lt;a href="https://eips.ethereum.org/EIPS/eip-1193#sendasync-deprecated" rel="noopener noreferrer"&gt;sendAsync&lt;/a&gt; vs &lt;a href="https://eips.ethereum.org/EIPS/eip-1193#send-deprecated" rel="noopener noreferrer"&gt;send&lt;/a&gt; function. This approach took an average of &lt;strong&gt;3042ms&lt;/strong&gt; out of 10 runs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pros of web3.js BatchRequest
&lt;/h3&gt;

&lt;h4&gt;
  
  
  More human-readable code
&lt;/h4&gt;

&lt;p&gt;Unlike GraphQL, the &lt;code&gt;BatchRequest&lt;/code&gt; method works on top of web3.js, which allows us to use the contract's ABI function names instead of encoding them, which makes the code more human-readable.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cons of web3.js BatchRequest
&lt;/h3&gt;

&lt;h4&gt;
  
  
  The library is still in development
&lt;/h4&gt;

&lt;p&gt;Currently the web3.js v2.0.0 library is still in development and it's very likely to contain breaking changes in the future.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;In this post, we investigated three different approaches you can take to read data from the Ethereum ledger. In our example scenario, GraphQL had the best average performance of 2289ms as compared to the Etherplex library and the web3.js &lt;code&gt;BatchRequest&lt;/code&gt; method.&lt;/p&gt;

&lt;p&gt;Below are the performance metrics we took:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2F4wh0Y3i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2F4wh0Y3i.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;GraphQL outperforms the other two approaches by close to 1 second.&lt;/p&gt;

&lt;p&gt;I personally suggest using GraphQL, not mainly because of its performance but also for its stability and flexibility.&lt;/p&gt;

&lt;p&gt;I hope this post inspires you to try using GraphQL for your use case. The GraphQL feature is supported on all our full and archive dedicated Ethereum nodes—&lt;a href="https://console.chainstack.com/" rel="noopener noreferrer"&gt;sign up&lt;/a&gt; with us and unlock unlimited possibility on direct and efficient queries to the ledger.&lt;/p&gt;

&lt;h2&gt;
  
  
  Join our community of innovators
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;To learn more about Chainstack, visit our &lt;a href="https://docs.chainstack.com/" rel="noopener noreferrer"&gt;Knowledge Center&lt;/a&gt; or join our &lt;a href="https://gitter.im/chainstack/Lobby" rel="noopener noreferrer"&gt;Gitter Lobby&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Sign up for a &lt;a href="https://console.chainstack.com/user/account/create" rel="noopener noreferrer"&gt;free Developer account&lt;/a&gt;, or explore the options offered by Growth or Business plans here.&lt;/li&gt;
&lt;li&gt;Take a look at our pricing tiers using a &lt;a href="https://chainstack.com/pricing/" rel="noopener noreferrer"&gt;handy calculator&lt;/a&gt; to estimate usage and number of nodes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Have you already explored what you can achieve with Chainstack? &lt;a href="https://console.chainstack.com/user/account/create" rel="noopener noreferrer"&gt;Get started for free today&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ethereum</category>
      <category>tokens</category>
      <category>web3</category>
      <category>graphql</category>
    </item>
    <item>
      <title>Eth2 and your DApps: What you need to know</title>
      <dc:creator>Eugene Aseev</dc:creator>
      <pubDate>Tue, 29 Dec 2020 06:14:32 +0000</pubDate>
      <link>https://dev.to/easeev/eth2-and-your-dapps-what-you-need-to-know-dbl</link>
      <guid>https://dev.to/easeev/eth2-and-your-dapps-what-you-need-to-know-dbl</guid>
      <description>&lt;p&gt;Do I as a DApp developer need to change my DApps and my DApp building routine and/or architecture?&lt;/p&gt;

&lt;p&gt;No. Your DApps are safe for at least a couple of years.&lt;/p&gt;

&lt;h2&gt;
  
  
  A longer explanation
&lt;/h2&gt;

&lt;p&gt;The complete Ethereum 2.0—officially referred to as Eth2—implementation and mainnet is rolled out in phases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Phase 0 — launched on December 1, 2020 with the Beacon Chain.&lt;/li&gt;
&lt;li&gt;  Phase 1 — tentative for 2021 with the introduction of shard chains.&lt;/li&gt;
&lt;li&gt;  Phase 1.5 — tentative for 2021 or 2022 with the docking of Eth1 to Eth2.&lt;/li&gt;
&lt;li&gt;  Phase 2 — no defined plans.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each of the phases introduces changes to Eth2 and how it interacts with Eth1 where your DApps are.&lt;/p&gt;

&lt;p&gt;Let's have a look at each of the phases and if they can potentially make you change the way you work with your DApps.&lt;/p&gt;

&lt;h2&gt;
  
  
  Will anything change for me after Phase 0 is initiated?
&lt;/h2&gt;

&lt;p&gt;No.&lt;/p&gt;

&lt;h3&gt;
  
  
  A longer explanation
&lt;/h3&gt;

&lt;p&gt;On December 1, 2020, the Beacon Chain launched and marked the official start of Phase 0.&lt;/p&gt;

&lt;p&gt;Whereas the Beacon Chain is the foundational component of Eth2, it's not the full Eth2 implementation.&lt;/p&gt;

&lt;p&gt;With the launch of Phase 1, the Beacon Chain will start validating shard chains. Until then, the Beacon Chain is a network of stakers validating blocks on the chain.&lt;/p&gt;

&lt;p&gt;The Beacon Chain itself cannot handle Ethereum accounts and smart contracts. Accounts and smart contracts can only be done on shard chains, and even that won't be immediately available in Phase 1.&lt;/p&gt;

&lt;p&gt;The Beacon Chain consists of Beacon nodes and Validator clients.&lt;/p&gt;

&lt;p&gt;To just keep an up-to-date copy of blocks on the Beacon Chain, you need a Beacon node.&lt;/p&gt;

&lt;p&gt;To be a validator on the Beacon Chain, you need both a Beacon node, a validator client, and an Eth1 node. The Beacon node connects to the Eth1 node to monitor the Eth2 staking deposit address on Eth1 for new validators on the Beacon Chain.&lt;/p&gt;

&lt;p&gt;The Eth1 mainnet itself is completely "unaware" of the existence of Eth2 in the form of Beacon Chain.&lt;/p&gt;

&lt;p&gt;Architecturally, your existing DApps or your DApp building routine won't see changes during Phase 0.&lt;/p&gt;

&lt;h2&gt;
  
  
  Will anything change for me after Phase 1 is initiated?
&lt;/h2&gt;

&lt;p&gt;No.&lt;/p&gt;

&lt;h3&gt;
  
  
  A longer explanation
&lt;/h3&gt;

&lt;p&gt;At some point in 2021, Eth2 will see the introduction of shard chains—the proof-of-stake chains running in parallel and coordinated by the Beacon Chain.&lt;/p&gt;

&lt;p&gt;The Beacon Chain will be assigning validators to the shard chains and will also keep the shards up-to-date with each other.&lt;/p&gt;

&lt;p&gt;The shard chains will first be introduced as version 1. In version 1, the shards will not be capable of executing smart contracts; they will only store the data necessary to execute smart contracts—for example, time stamps, oracle data, byte information required to interact with other shards.&lt;/p&gt;

&lt;p&gt;Version 2—when or if introduced—will see the execution of smart contracts on the shards.&lt;/p&gt;

&lt;p&gt;Architecturally, your existing DApps or your DApp building routine won't see changes during Phase 1.&lt;/p&gt;

&lt;h2&gt;
  
  
  Will anything change for me after Phase 1.5 is initiated?
&lt;/h2&gt;

&lt;p&gt;No, but your DApps will start responding faster, since this is when Eth2 will presumably be locked to 12 second blocks.&lt;/p&gt;

&lt;p&gt;You won't have to change in your smart contracts, but the centralized parts of your DApps—e.g., a web app—will be fetching a quicker response to your users.&lt;/p&gt;

&lt;h3&gt;
  
  
  A longer explanation
&lt;/h3&gt;

&lt;p&gt;In 2021 or 2022, the Eth1 mainnet will switch from the current proof-of-work to the proof-of-stake consensus algorithm and will be "docked" into Eth2. The process of docking, in this case, means that the Eth1 mainnet will become one of the shards of Eth2 coordinated by the Beacon Chain.&lt;/p&gt;

&lt;p&gt;Architecturally, your existing DApps or your DApp building routine won't see changes during Phase 1.5.&lt;/p&gt;

&lt;h2&gt;
  
  
  Will anything change for me after Phase 2 is initiated?
&lt;/h2&gt;

&lt;p&gt;Yes, but what exactly will change is uncertain at this point.&lt;/p&gt;

&lt;h3&gt;
  
  
  A longer explanation
&lt;/h3&gt;

&lt;p&gt;As of today, Phase 2 is not clearly defined, however this is when you might see the most changes affecting you as a DApp developer as it may have the introduction of a new Ethereum Virtual Machine.&lt;/p&gt;

&lt;p&gt;Your existing DApps and your DApp building routine will see significant changes during Phase 2. However, at this point, there is no defined strategy on how you can be prepared for the changes other than staying up-to-date with the Eth2 developments and being a Chainstack user.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://console.chainstack.com/user/account/create"&gt;With Chainstack&lt;/a&gt;, you will be prepared for Phase 2 with as little effort from you as possible---the infrastructure migration will be as seamless as viable, you will be notified of the necessary changes on your end well in advance and be supported by our extensive documentation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Run an Eth1 node for your Eth2 client today
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://console.chainstack.com/user/account/create"&gt;Run a reliable dedicated Eth1 node&lt;/a&gt; that you can link to your Beacon node.&lt;/p&gt;

&lt;p&gt;See also &lt;a href="https://support.chainstack.com/hc/en-us/articles/900004755663-Connecting-your-Chainstack-Eth1-node-to-a-Prysm-Beacon-node"&gt;Connecting your Chainstack Eth1 node to a Prysm Beacon node&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get early access to Eth2 nodes
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://pages.chainstack.com/ethereum-2.0"&gt;Contact us to get an early access to Eth2 nodes&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Join our community of innovators
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  To learn more about Chainstack, visit our &lt;a href="https://docs.chainstack.com/"&gt;Knowledge Center&lt;/a&gt; or join our &lt;a href="https://gitter.im/chainstack/Lobby"&gt;Gitter Lobby&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;  Sign up for a &lt;a href="https://console.chainstack.com/user/account/create"&gt;free Developer account&lt;/a&gt;, or explore the options offered by &lt;a href="https://chainstack.com/pricing/"&gt;Growth or Business plans&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;  Take a look at our pricing tiers using a &lt;a href="https://chainstack.com/pricing/"&gt;handy calculator&lt;/a&gt; to estimate usage and number of nodes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Have you already explored what you can achieve with Chainstack? &lt;a href="https://console.chainstack.com/user/account/create"&gt;Get started for free today&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>ethereum</category>
      <category>eth2</category>
      <category>dapps</category>
    </item>
    <item>
      <title>Exploring the methods of looking into Ethereum’s transaction pool</title>
      <dc:creator>Eugene Aseev</dc:creator>
      <pubDate>Thu, 24 Dec 2020 03:23:59 +0000</pubDate>
      <link>https://dev.to/easeev/exploring-the-methods-of-looking-into-ethereum-s-transaction-pool-3j0o</link>
      <guid>https://dev.to/easeev/exploring-the-methods-of-looking-into-ethereum-s-transaction-pool-3j0o</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;The mempool of the Ethereum mainnet—called transaction pool or txpool—is the dynamic in-memory area where pending transactions reside before they are included in a block and thus become static.&lt;/p&gt;

&lt;p&gt;The notion of a global txpool is a bit abstract as there is no single defined pool for all pending transactions. Instead, each node on the Ethereum mainnet has its own pool of transactions and, combined, they all form the global pool.&lt;/p&gt;

&lt;p&gt;The thousands of pending transactions that enter the global pool by being broadcast on the network and before being included in a block are an always changing data set that's holding millions of dollars at any given second.&lt;/p&gt;

&lt;p&gt;There's a lot that one can do here—and many do and make this txpool business a highly competitive market.&lt;/p&gt;

&lt;p&gt;A few examples, listed in the order of inconspicuous to contentious:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Yield farming — you can watch the transactions movement between DeFi applications to be one of the first to detect the yield farming profitability changes.&lt;/li&gt;
&lt;li&gt;  Liquidity providing — you detect the potential liquidity movements in and out of DeFi applications and act on the changes.&lt;/li&gt;
&lt;li&gt;  Arbitrage — you can detect the movement of transactions that will affect token prices at different DEXes and make your arbitrage trades based on that.&lt;/li&gt;
&lt;li&gt;  Front running — you can automatically grab the existing pending transactions, simulate them to identify the potential profit if the transaction is executed, copy the transaction and swap the existing address with your own, and submit it with a higher miner fee so that your transaction gets executed on-chain before the one you are copying.&lt;/li&gt;
&lt;li&gt;  Doing a MEV — MEV stands for Miner Extractable Value, and it's based on that miners are theoretically free to include any transactions in the blocks and/or reorder them. This is a variation of the front running where instead of submitting your transaction with a higher fee to the same pool you picked it from, you get it directly into a block through a miner and bypass the pool.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To run any of the described scenarios, you need access to the Ethereum txpool, and you need the methods to retrieve the transactions from the txpool. While Chainstack has you covered with fast dedicated nodes for the former, this article focuses on all the ways you can look into the txpool.&lt;/p&gt;

&lt;h2&gt;
  
  
  Retrieving pending transactions with Geth
&lt;/h2&gt;

&lt;p&gt;Since pending transactions are your targets in the txpool space, we are now going to make this a structured effort and focus on answering the following questions while accompanying the answers with practical examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  How do I retrieve pending transactions?&lt;/li&gt;
&lt;li&gt;  Why do I view global or local pending transactions?&lt;/li&gt;
&lt;li&gt;  Can I view global pending transactions without txpool namespace?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are a few ways to retrieve pending transactions.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Filters&lt;/li&gt;
&lt;li&gt;  Subscriptions&lt;/li&gt;
&lt;li&gt;  Txpool API&lt;/li&gt;
&lt;li&gt;  GraphQL API&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Before we start, lets clarify a few things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Global pending transactions&lt;/strong&gt; refer to pending transactions that are happening globally, which includes your newly created local pending transactions.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Local pending transactions&lt;/strong&gt; refer strictly to the transactions that you created on your local node. Note that you need 'personal' namespace enabled for Geth to send local transactions.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Pending transactions&lt;/strong&gt; refer to transactions that are pending due to various reasons, like extremely low gas, out of order nonce, etc.&lt;/li&gt;
&lt;li&gt;  Chainstack is using &lt;strong&gt;Geth (Go Ethereum)&lt;/strong&gt; client.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Filters
&lt;/h3&gt;

&lt;p&gt;When we create a filter on Geth, Geth will return a unique &lt;code&gt;filter_id&lt;/code&gt;. Do note that this &lt;code&gt;filter_id&lt;/code&gt; will only live for 5 minutes from the last query on that specific filter. If you query this filter after 5 minutes, the filter will not exist anymore.&lt;/p&gt;

&lt;h4&gt;
  
  
  Creating a pending transaction filter and retrieving data from it
&lt;/h4&gt;

&lt;h5&gt;
  
  
  cURL
&lt;/h5&gt;

&lt;p&gt;&lt;strong&gt;Create filter&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Request body:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;'{"jsonrpc":"2.0","method":"eth_newPendingTransactionFilter","params":[],"id":73}'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Response body:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{ "id":73, "jsonrpc": "2.0", "result": "0xb337f6e2f833ecffc6e9315ba06cd03d" }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  Web3.js
&lt;/h5&gt;

&lt;p&gt;Filter for pending transactions is not supported anymore. Please use &lt;a href="https://chainstack.com/exploring-the-methods-of-looking-into-ethereums-transaction-pool/#subscriptions"&gt;Subscriptions&lt;/a&gt;.&lt;/p&gt;

&lt;h5&gt;
  
  
  Web3.py
&lt;/h5&gt;

&lt;p&gt;&lt;strong&gt;Create filter&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pending_transaction_filter= web3.eth.filter('pending')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Access filter&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;print(pending_transaction_filter.get_new_entries())
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Common sources of confusion on filters
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Web3.py and the pending argument
&lt;/h4&gt;

&lt;p&gt;Why does web3.py have their input arguments as &lt;em&gt;pending&lt;/em&gt; instead of a dictionary which contains the usual filter parameters like &lt;code&gt;fromBlock&lt;/code&gt;, &lt;code&gt;toBlock&lt;/code&gt;, &lt;code&gt;address&lt;/code&gt;, &lt;code&gt;topics&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This is because Web3 does the mapping internally. If we look at the &lt;a href="https://github.com/ethereum/web3.py/blob/72457e6f9f3cb6d51fe492d1a65bed7904639760/web3/eth.py#L474"&gt;web3.py source code&lt;/a&gt;, when web3.py receives a string pending, it will be mapped to &lt;code&gt;eth_newPendingTransactionFilter&lt;/code&gt;, and when web3.py receives a dictionary, it is mapped to &lt;code&gt;eth_newFilter&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To add to this, web3.py has &lt;code&gt;get_new_entries&lt;/code&gt; as well as &lt;code&gt;get_all_entries&lt;/code&gt; for filters but &lt;code&gt;get_all_entries&lt;/code&gt; does not work in our case. This is because &lt;code&gt;eth_newPendingTransactionFilter&lt;/code&gt; does not have &lt;code&gt;get_all_entries&lt;/code&gt; available for it.&lt;/p&gt;

&lt;h4&gt;
  
  
  From latest block to pending block filter
&lt;/h4&gt;

&lt;p&gt;Why doesn't the following filter give me real-time pending transactions?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;web3.eth.filter({'fromBlock': 'latest', 'toBlock': 'pending'})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A filter only returns &lt;code&gt;new_entries()&lt;/code&gt; when the state has changed. This specific filter state changes only when there is a new latest block or pending block. Thus, you will only receive changes when there is a new latest block or pending block, i.e. &lt;code&gt;(eth.getBlock('latest') / pending)&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  The getPendingTransactions filter
&lt;/h4&gt;

&lt;p&gt;Why is the following giving me a different or empty result?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;web3.eth.getPendingTransactions().then(console.log)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This function is mapped to &lt;code&gt;eth.pendingTransactions&lt;/code&gt; which is a function to check local pending transactions and does not give you global transactions.&lt;/p&gt;

&lt;p&gt;Based on the &lt;a href="https://github.com/ethereum/go-ethereum/blob/ead814616c094331915b03edd82d4200a7880178/internal/ethapi/api.go#L1700"&gt;Geth source code&lt;/a&gt;, only &lt;code&gt;pendingTransactions&lt;/code&gt; that has its &lt;code&gt;from&lt;/code&gt; field matching with your personal account will be shown.&lt;/p&gt;

&lt;h3&gt;
  
  
  Subscriptions
&lt;/h3&gt;

&lt;p&gt;Subscriptions is real-time streaming of data from server to client through WebSocket. You will need a constantly active connection to stream such events. You cannot use curl for this and have to use a WebSocket client like &lt;a href="https://github.com/vi/websocat"&gt;websocat&lt;/a&gt; if you want to access it via command line. Once executed, a stream of pending transaction IDs will start flowing in.&lt;/p&gt;

&lt;p&gt;For other supported subscriptions, check the Geth documentation: &lt;a href="https://geth.ethereum.org/docs/rpc/pubsub#supported-subscriptions"&gt;Supported Subscriptions&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Creating a subscription
&lt;/h4&gt;

&lt;h5&gt;
  
  
  Websocat
&lt;/h5&gt;

&lt;p&gt;&lt;strong&gt;Connect to node&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;websocat wss://username:password@ws-nd-123-456-789.p2pify.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Create subscription&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Request body:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{"id": 1, "method": "eth_subscribe", "params": ["newPendingTransactions"]}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Response body:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{"jsonrpc":"2.0","id":1,"result":"0x2d4f3eb938cdb0b6fa9052de7c4da5de"}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Incoming stream&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{"jsonrpc":"2.0","method":"eth_subscription","params":{"subscription":"0x2d4f3eb938cdb0b6fa9052de7c4da5de","result":"0xee426dbaef2a432d0433d5de600347e97b6a8a855daf8765c18cf1b7efc53461"}}
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Txpool API
&lt;/h3&gt;

&lt;p&gt;Txpool is a Geth-specific API namespace that keeps pending and queued transactions in the local memory pool. Geth's default is 4096 pending and 1024 queued transactions. However, &lt;a href="https://etherscan.io/txsPending"&gt;Etherescan reports&lt;/a&gt; a much bigger number of pending transactions. If we view Geth's txpool, we will not be able to get all of the transactions. Once the pool of 4096 is full, Geth replaces older pending values with newer pending transactions.&lt;/p&gt;

&lt;p&gt;If you need a bigger pool to be stored on your node, the flag &lt;code&gt;--txpool.globalslots&lt;/code&gt; can be adjusted to a higher value on &lt;a href="https://geth.ethereum.org/docs/interface/command-line-options"&gt;Geth CLI options&lt;/a&gt;. Do note that the larger the number, the bigger the payload size.&lt;/p&gt;

&lt;p&gt;If you see your &lt;code&gt;txpool_status&lt;/code&gt; to be empty, it can mean your node has not fully synced.&lt;/p&gt;

&lt;p&gt;The txpool namespace is only supported on Chainstack dedicated nodes.&lt;/p&gt;

&lt;h4&gt;
  
  
  Creating a txpool filter
&lt;/h4&gt;

&lt;h5&gt;
  
  
  cURL
&lt;/h5&gt;

&lt;p&gt;&lt;strong&gt;Create filter&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Request body:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{"jsonrpc":"2.0","method":"eth_newPendingTransactionFilter","params":[],"id":73}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Response body:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{ "jsonrpc": "2.0", "id": 73, "result": { "pending": {...}, "queued": {...} } }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  Web3.js
&lt;/h5&gt;

&lt;p&gt;&lt;a href="https://web3js.readthedocs.io/en/v2.0.0-alpha/web3-eth-txpool.html"&gt;TxPool Module&lt;/a&gt;.&lt;/p&gt;

&lt;h5&gt;
  
  
  Web3.py
&lt;/h5&gt;

&lt;p&gt;&lt;a href="https://web3py.readthedocs.io/en/stable/web3.geth.html"&gt;Geth API&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  GraphQL API
&lt;/h3&gt;

&lt;p&gt;The biggest advantage of &lt;a href="https://chainstack.com/graphql-on-ethereum-availability-on-chainstack-and-a-quick-rundown/"&gt;using GraphQL&lt;/a&gt; is that you can filter out the specific fields of the transaction that you want. The query in GraphQL goes through the elements within the txpool. Thus, its limitations are the same as the ones of txpool as stated above.&lt;/p&gt;

&lt;p&gt;The following is an example which shows the information of a pending transaction.&lt;/p&gt;

&lt;p&gt;Query example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;query {
  pending {
    transactions {
      hash
      gas
      value
      gasPrice
      nonce
      r
      s
      v
      inputData
      status
      gasUsed
      cumulativeGasUsed
      from {
        address
      }
      to {
        address
      }
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;GraphQL API is currently supported on Chainstack &lt;a href="https://chainstack.com/pricing/"&gt;dedicated Ethereum nodes&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I hope this blog serves you well in understanding the various ways of retrieving pending transactions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Additional resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://web3js.readthedocs.io/en/v1.3.0/web3-eth.html"&gt;Web3.eth&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://eth.wiki/json-rpc/API"&gt;Ethereum JSON-RPC API&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://support.chainstack.com/hc/en-us/articles/900000820506-Checking-pending-and-queued-transactions-in-your-Ethereum-node-s-local-pool"&gt;Checking pending and queued transactions in your Ethereum node's local pool&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://support.chainstack.com/hc/en-us/articles/900003426246-Subscribing-to-global-new-pending-transactions"&gt;Subscribing to global new pending transactions&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Join our community of innovators
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  To learn more about Chainstack, visit our &lt;a href="https://docs.chainstack.com/"&gt;Knowledge Center&lt;/a&gt; or join our &lt;a href="https://gitter.im/chainstack/Lobby"&gt;Gitter Lobby&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;  Sign up for a &lt;a href="https://console.chainstack.com/user/account/create"&gt;free Developer account&lt;/a&gt;, or explore the options offered by &lt;a href="https://chainstack.com/pricing/"&gt;Growth or Business plans&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;  Take a look at our pricing tiers using a &lt;a href="https://chainstack.com/pricing/"&gt;handy calculator&lt;/a&gt; to estimate usage and number of nodes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Have you already explored what you can achieve with Chainstack? &lt;a href="https://console.chainstack.com/user/account/create"&gt;Get started for free today&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>ethereum</category>
      <category>txpool</category>
      <category>mempool</category>
    </item>
  </channel>
</rss>
