joshstevens19 / ethereum-multicall

Ability to call many ethereum constant function calls in 1 JSONRPC request
MIT License
367 stars 94 forks source link

Archive data request #87

Open radisa-bogdanovic opened 9 months ago

radisa-bogdanovic commented 9 months ago

If i get request for multicall data on specific block wich happened in 2023 i getting result as i should, but if i request data for Eth from 2019 im getting this error:

Error: call revert exception [ See: https://links.ethers.org/v5-errors-CALL_EXCEPTION ] (method="tryBlockAndAggregate(bool,(address,bytes)[])", data="0x", errorArgs=null, errorName=null, errorSignature=null, reason=null, code=CALL_EXCEPTION, version=abi/5.7.0) at Logger.makeError (index.ts:269:1) at Logger.throwError (index.ts:281:1) at Interface.decodeFunctionResult (interface.ts:427:1) at Object. (index.ts:400:1) at Generator.next () at fulfilled (index.ts:1:1)

Is this because there is no data for that time so i can return emty result or i making some mistake.? I'm using this multicontractAddress : 0xcA11bde05977b3631167028862bE2a173976CA11 Also im using Merkle as provider

joshstevens19 commented 9 months ago

can you write me a little demo script and i can debug

radisa-bogdanovic commented 9 months ago

Hello Josh, thank you for answering; Here it is script

import { Multicall, ContractCallResults, ContractCallContext, } from "ethereum-multicall"; import Web3 from "web3";

import { NetworkCoinToken } from "../models/models";

export const GetFinalResultv2 = async () => { let tokens: any[] = [ { id: 3, name: "BNB", shortName: "BNB", contractAddress: "0xb8c77482e45f1f44de1745f52c74426c631bdd52", decimalPlaces: 18, networkId: 2, }, { id: 6, name: "Uniswap", shortName: "UNI", contractAddress: "0x1f9840a85d5af5bf1d1762f925bdaddc4201f984", networkId: 2, }, ]; const walletAddress = "0xA9D1e08C7793af67e9d92fe308d5697FB81d3E43"; const contractCallContext: ContractCallContext[] = tokens.map( (token: NetworkCoinToken) => ({ reference: token.contractAddress || "", context: token.name, contractAddress: token.contractAddress || "", abi: [ { name: "balanceOf", type: "function", stateMutability: "view", inputs: [ { name: "_owner", type: "address", }, ], outputs: [ { name: "balance", type: "uint256", }, ], }, ], calls: [ { reference: token.contractAddress || "", methodName: "balanceOf", methodParameters: [walletAddress || ""], }, ], }) );

const multicall = new Multicall({
    tryAggregate: true,
    multicallCustomContractAddress:
        "0xcA11bde05977b3631167028862bE2a173976CA11",
    nodeUrl: "https://eth.merkle.io",
});

const getBlock = async (url: string) => {
    try {
        const web3 = new Web3(url);
        const block = await web3.eth.getBlock(14353600);

        return block;
    } catch (error: any) {
        console.log(error);
    }
};
const getData = async () => {
    let resultData: ContractCallResults | null = null;

    try {
        const numberBl = await getBlock("https://eth.merkle.io");

        resultData = await multicall.call(contractCallContext, {
            blockNumber: Number(numberBl?.number).toString(),
        });

        if (resultData) {
            const currentResult =
                resultData?.results[0]?.callsReturnContext[0]?.returnValues[0]?.hex;
            const balance = currentResult ? BigInt(currentResult).toString() : "0";
            console.log(balance);
            return resultData;
            // const balanceFormated = formatBalance(balance, numberToFormat);
        }
    } catch (error: any) {
        console.log(error);
    }
};
const finalData: any = (await getData()) || [];

console.log(finalData);

return finalData;

}; It works for me from the date when the multicall address was deployed on etherscan. https://etherscan.io/address/0xca11bde05977b3631167028862be2a173976ca11#code

radisa-bogdanovic commented 9 months ago

I asked Matt from mds1 for same issue and he told me : "This is correct, you will not be able to use Multicall3 to read historical data from before Multicall3 was deployed. A workaround is to use geth's state overrides and place the Multicall3 bytecode at the expected address as part of your call." Can i somehow do workaround using this libary. And also can i provide chainId without requesting to get him from get_chainId or net_version bcs i already know wich chainId i want?