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
你可以看一下@0xsequence/multicall
。它包括:
multiCall()
用于进行聚合调用的功能MultiCallUtils
部署在 Rootstock 测试网上:0xb39d1Dea1bF91Aef02484F677925904b9d6936B4
npm i @0xsequence/multicall
Run Code Online (Sandbox Code Playgroud)
const { providers } = require('@0xsequence/multicall');
Run Code Online (Sandbox Code Playgroud)
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)
const multicallProvider = new providers.MulticallProvider(ethersProvider, multicallConfig[31]);
Run Code Online (Sandbox Code Playgroud)
const token1 = new ethers.Contract(
token1Address,
token1ABI,
multicallProvider,
);
const token2 = ...
Run Code Online (Sandbox Code Playgroud)
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 提供程序单独调用其组成函数调用。
makeAggregatedCall
函数附加到以太坊提供者block
事件侦听器:ethersProvider.on('block', makeAggregatedCall);
Run Code Online (Sandbox Code Playgroud)
您可以使用该ethereum-multicall
项目,其中包括:
该项目的优点是 Rootstock 主网和 Rootstock 测试网都有部署Multicall3
:
...以及个性化地址的奖励积分0xca11...ca11
;)
npm i ethereum-multicall
Run Code Online (Sandbox Code Playgroud)
const { Multicall } = require('ethereum-multicall');
Run Code Online (Sandbox Code Playgroud)
const multicall = new Multicall({
ethersProvider: ethersProvider,
tryAggregate: true,
});
Run Code Online (Sandbox Code Playgroud)
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)
results
从对象中提取所需的数据