赞
踩
场景,发送N个rpc请求
Tip: 以下调用的合约与https://web03.cn/blog/257是一样的
console.time('A')
const web3 = new Web3(new Web3.providers.HttpProvider('https://bsc-dataseed.binance.org/'))
var myContractInstance = new web3.eth.Contract(ABI, '0x948d2a81086A075b3130BAc19e4c6DEe1D2E3fE8');
const promiseArr = []
for (let i = 0; i < 10; i++) {
promiseArr.push(myContractInstance.methods.balanceOf('0x23FCB0E1DDbC821Bd26D5429BA13B7D5c96C0DE0').call())
}
Promise.all(promiseArr).then(res => {
console.timeEnd('A')
console.log(res)
})
注意:可能发送20个就会导致一些rpc失败,可能100个…,rpc数量越多,失败概率越高
https://www.npmjs.com/package/ethers-multicall-x
npm install ethers-multicall-x
npm install @ethersproject/providers
console.time('B')
const concat = new Contract('0x948d2a81086A075b3130BAc19e4c6DEe1D2E3fE8', ABI)
const promiseArr = []
for (let i = 0; i < 100; i++) {
promiseArr.push(concat.balanceOf('0x23FCB0E1DDbC821Bd26D5429BA13B7D5c96C0DE0'))
}
const provider = new JsonRpcProvider('https://bsc-dataseed.binance.org/', 56)
const multiCallProvider = new Provider(provider, 56);
multiCallProvider.all(promiseArr).then(res => {
console.timeEnd('B')
console.log(res)
})
你会发现它的数据都是BigNumber类型,需要手动解析
function processResult(data) {
if (Array.isArray(data)){
data.map((o, i) => {
data[i] = processResult(o)
})
return data
}else if(data.toString){
return data.toString()
} else{
return data
}
}
processResult(result)
将所有的rpc请求方法一次性提交给插件,插件通过自己的合约去调用目标合约的方法,拿到所有返回的内容后再返回给用户,相当于是中间代理,合约对合约的交互调用,省去了RPC请求
为了减少消耗,可以将ethers-multicall-x进行封装,只在第一次调用的时候进行初始化实例对象
import Web3 from "web3"; import ABI from '../ABI/abi.json' import {Contract,Provider, setMulticallAddress} from "ethers-multicall-x"; import {JsonRpcProvider} from "@ethersproject/providers"; const ChainId = { BSC: 56 } const ChainConfig = (chainId) => { return { [ChainId.BSC]: { rpc_url: 'https://bsc-dataseed.binance.org/', abi: ABI, address: '0x948d2a81086A075b3130BAc19e4c6DEe1D2E3fE8' } }[chainId] } const _CONTRACT = {} export const getContract = (chainId) =>{ // 如果相同的chainId不同的address或者abi,此步骤是多余的,没必要缓存 if (_CONTRACT[chainId]) { return _CONTRACT[chainId] } const config = ChainConfig(chainId) console.log(config) return _CONTRACT[chainId] = new Contract(config.address, config.abi) } let _PROVIDER = {} export const getMultiCallProvider = (chainId) =>{ if (_PROVIDER[chainId]) { return _PROVIDER[chainId] } const provider = new JsonRpcProvider(ChainConfig(chainId).rpc_url, chainId) // 添加插件外的链配置 setMulticallAddress(137, "0x11ce4B23bD875D7F5C6a31084f55fDe1e9A87507") return _PROVIDER[chainId] = new Provider(provider, chainId); }
const concat = getContract(ChainId.BSC)
const multiCallProvider = getMultiCallProvider(ChainId.BSC)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。