如何聚合Rootstock上的多个智能合约函数调用?

bgu*_*uiz 6 javascript solidity rsk ethers.js

我有多个 ERC20 代币,部署在Rootstock上,我想从我的 DApp 实时跟踪它们的余额和配额。在ethers.js中,我可以通过交替调用函数 balanceOf(address)和来跟踪它们的余额allowance(owner, spender)。但是,对于两个令牌,这相当于每约 30 秒发出约 4 个 JSON-RPC 请求。

我更愿意通过聚合这些特定请求来降低应用程序发出 JSON-RPC 请求的频率。

是否可以通过或任何其他库将多个智能合约数据查询组合到单个 JSON-RPC 请求中?ethers.js

Ale*_*hin 7

你可以看一下@0xsequence/multicall。它包括:

智能合约部署:

要进行聚合智能合约调用:

  1. 安装 npm 包:
npm i @0xsequence/multicall
Run Code Online (Sandbox Code Playgroud)
  1. 将库导入到您的项目中:
const { providers } = require('@0xsequence/multicall');
Run Code Online (Sandbox Code Playgroud)
  1. 创建 Rootstock 测试网配置:
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',
  },
};
Run Code Online (Sandbox Code Playgroud)
  1. 使用 Multicall 提供程序包装您的 ethers.js 当前提供程序:
const multicallProvider = new providers.MulticallProvider(ethersProvider, multicallConfig[31]);
Run Code Online (Sandbox Code Playgroud)
  1. 将您的代币智能合约连接到 Multicall 提供商而不是 ethers.js 提供商,以便能够进行聚合调用:
const token1 = new ethers.Contract(
    token1Address,
    token1ABI,
    multicallProvider,
  );
const token2 = ...
Run Code Online (Sandbox Code Playgroud)
  1. 现在您已准备好创建聚合调用:
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);
}
Run Code Online (Sandbox Code Playgroud)

MultiCallUtils该库将尝试在对智能合约函数的单个调用中发送所有这些函数调用multiCall()。但是,如果聚合调用失败,作为后备措施,将通过 ethers.js 提供程序单独调用其组成函数调用。

  1. 为了订阅每个新创建的块,请将makeAggregatedCall函数附加到以太坊提供者block事件侦听器:
ethersProvider.on('block', makeAggregatedCall);
Run Code Online (Sandbox Code Playgroud)


Ale*_*hin 5

您可以使用该ethereum-multicall项目,其中包括:

智能合约部署:

该项目的优点是 Rootstock 主网和 Rootstock 测试网都有部署Multicall3

...以及个性化地址的奖励积分0xca11...ca11;)

要进行聚合智能合约调用:

  1. 安装 npm 包:
npm i ethereum-multicall
Run Code Online (Sandbox Code Playgroud)
  1. 将库导入到您的项目中:
const { Multicall } = require('ethereum-multicall');
Run Code Online (Sandbox Code Playgroud)
  1. 创建 Multicall 实例并将其连接到 ethers.js 提供程序
const multicall = new Multicall({
    ethersProvider: ethersProvider,
    tryAggregate: true,
});
Run Code Online (Sandbox Code Playgroud)
  1. 创建聚合调用:
  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);
Run Code Online (Sandbox Code Playgroud)
  1. results从对象中提取所需的数据