最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to aggregate multiple smart contract function calls on Rootstock? - Stack Overflow

programmeradmin1浏览0评论

I have multiple ERC20 tokens, deployed on Rootstock, and I want to track their balances and allowances in a real time from my DApp. In ethers.js, I can track their balances by alternately calling the functions balanceOf(address) and allowance(owner, spender). However, across two tokens, that equates to about 4 JSON-RPC requests every ~30 seconds.

I would prefer to reduce the frequency of JSON-RPC requests made by my application, by aggregating these particular requests.

Is it possible to bine multiple smart contract data queries into a single JSON-RPC request via ethers.js or any other library?

I have multiple ERC20 tokens, deployed on Rootstock, and I want to track their balances and allowances in a real time from my DApp. In ethers.js, I can track their balances by alternately calling the functions balanceOf(address) and allowance(owner, spender). However, across two tokens, that equates to about 4 JSON-RPC requests every ~30 seconds.

I would prefer to reduce the frequency of JSON-RPC requests made by my application, by aggregating these particular requests.

Is it possible to bine multiple smart contract data queries into a single JSON-RPC request via ethers.js or any other library?

Share Improve this question edited Apr 30, 2023 at 12:48 bguiz asked Nov 8, 2022 at 8:00 bguizbguiz 28.5k49 gold badges163 silver badges251 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 7

You could take a look at @0xsequence/multicall. It consists of:

  • MultiCallUtils smart contract with a multiCall() function intended for making aggregated calls
  • JS frontend library which includes a Multicall wrapper around ethers.js provider.

Smart contract deployments:

  • MultiCallUtils is deployed on the Rootstock Testnet: 0xb39d1Dea1bF91Aef02484F677925904b9d6936B4
  • I am not sure whether it is deployed at Rootstock Mainnet or not, anyway, you can deploy it there yourself.

To make aggregated smart contract calls:

  1. Install the npm package:
npm i @0xsequence/multicall
  1. Import the library to your project:
const { providers } = require('@0xsequence/multicall');
  1. Create a Rootstock Testnet configuration:
const multicallConfig = {
  // RSK Testnet
  31: {
    // maximum number of calls to batch into a single JSON-RPC call
    batchSize: 50,
    // defines the time each call is held on buffer waiting for subsequent calls before aggregation, ms
    timeWindow: 50,
    // MultiCallUtils smart contract
    contract: '0xb39d1Dea1bF91Aef02484F677925904b9d6936B4',
  },
};
  1. Wrap your ethers.js current provider with a Multicall provider:
const multicallProvider = new providers.MulticallProvider(ethersProvider, multicallConfig[31]);
  1. Connect your token smart contracts to the Multicall provider instead of ethers.js provider to be to able make aggregated calls:
const token1 = new ethers.Contract(
    token1Address,
    token1ABI,
    multicallProvider,
  );
const token2 = ...
  1. Now you are ready to create an aggregated call:
function makeAggregatedCall() {
  const aggregatedCall = [
    multicallProvider.getBalance(address),
    token1.balanceOf(address),
    token1.allowance(owner, spender),
    token2.balanceOf(address),
    token2.allowance(owner, spender),
  ];
  [
    rbtcBalance,
    balance1,
    allowance1,
    balance2,
    allowance2,
  ] = await Promise.all(aggregatedCall);
}

The library will attempt to send all these function calls within a single call to MultiCallUtils smart contract multiCall() function. However if the aggregated call fails, as a fallback, its constituent functions calls will be called individually via the ethers.js provider.

  1. In order to subscribe to every newly minted block, attach the makeAggregatedCall function to the ethers provider block event listener:
ethersProvider.on('block', makeAggregatedCall);

You could use the ethereum-multicall project, which consists of:

  • Frontend library which connects to
  • Multicall3 smart contract

Smart contract deployments:

The advantage of this project is that both Rootstock Mainnet and Rootstock Testnet have the Multicall3 deployments:

  • Mainnet 0xcA11bde05977b3631167028862bE2a173976CA11
  • Testnet 0xcA11bde05977b3631167028862bE2a173976CA11

... and bonus points for the 0xca11...ca11 vanity address ;)

To make aggregated smart contract calls:

  1. Install the npm package:
npm i ethereum-multicall
  1. Import the library to your project:
const { Multicall } = require('ethereum-multicall');
  1. Create Multicall instance and connect it to ethers.js provider
const multicall = new Multicall({
    ethersProvider: ethersProvider,
    tryAggregate: true,
});
  1. Create aggregated call:
  const aggregatedCall = [
    {
      reference: 'token1',
      contractAddress: token1Address,
      abi: token1ABI,
      calls: [
        {
          methodName: 'balanceOf',
          methodParameters: [walletAddress],
        },
        {
          methodName: 'allowance',
          methodParameters: [ownerAddress, spenderAddress],
        },
      ],
    },
    {
      reference: 'token2',
      contractAddress: token2Address,
      abi: token2ABI,
      calls: [
        {
          methodName: 'balanceOf',
          methodParameters: [walletAddress],
        },
        {
          methodName: 'allowance',
          methodParameters: [ownerAddress, spenderAddress],
        },
      ],
    },
  ];
  const { results } = await multicall.call(aggregatedCall);
  1. Extract the required data from the results object
发布评论

评论列表(0)

  1. 暂无评论