Skip to content

Example: Multicall  #39

@juanfranblanco

Description

@juanfranblanco
using System;
using System.Numerics;
using System.Threading.Tasks;
using Nethereum.Web3;
using Nethereum.ABI.FunctionEncoding.Attributes;
using Nethereum.Contracts;
using System.Collections.Generic;
using Nethereum.Hex.HexConvertors.Extensions;


public class Program
{
    //Example of using multicall https://github.com/makerdao/multicall/blob/master/src/Multicall.sol
    //calling contract deployed at https://etherscan.io/address/0xeefBa1e63905eF1D7ACbA5a8513c70307C1cE441#code

    [Function("balanceOf", "uint256")]
    public class BalanceOfFunction : FunctionMessage
    {
        [Parameter("address", "_owner", 1)] public string Owner { get; set; }
    }


    public partial class Call : CallBase { }

    public class CallBase
    {
        [Parameter("address", "target", 1)]
        public virtual string Target { get; set; }
        [Parameter("bytes", "callData", 2)]
        public virtual byte[] CallData { get; set; }
    }

    public partial class AggregateFunction : AggregateFunctionBase { }

    [Function("aggregate", typeof(AggregateOutputDTO))]
    public class AggregateFunctionBase : FunctionMessage
    {
        [Parameter("tuple[]", "calls", 1)]
        public virtual List<Call> Calls { get; set; }
    }

    public partial class AggregateOutputDTO : AggregateOutputDTOBase { }

    [FunctionOutput]
    public class AggregateOutputDTOBase : IFunctionOutputDTO
    {
        [Parameter("uint256", "blockNumber", 1)]
        public virtual BigInteger BlockNumber { get; set; }
        [Parameter("bytes[]", "returnData", 2)]
        public virtual List<byte[]> ReturnData { get; set; }
    }


    [FunctionOutput]
    public class BalanceOfOutputDTO : IFunctionOutputDTO
    {
        [Parameter("uint256", "balance", 1)]
        public BigInteger Balance { get; set; }
    }


    //async Task Main to enable async methods

    private static async Task Main(string[] args)
    {
        //Connecting to Ethereum mainnet using Infura
        var web3 = new Web3("https://mainnet.infura.io/v3/7238211010344719ad14a89db874158c");

        //Setting the owner https://etherscan.io/tokenholdings?a=0x8ee7d9235e01e6b42345120b5d270bdb763624c7
        var balanceOfMessage1 = new BalanceOfFunction() { Owner = "0x8ee7d9235e01e6b42345120b5d270bdb763624c7" };
        var call1 = new Call();
        call1.CallData = balanceOfMessage1.GetCallData();
        call1.Target = "0x9f8f72aa9304c8b593d555f12ef6589cc3a579a2";

        var balanceOfMessage2 = new BalanceOfFunction() { Owner = "0x8ee7d9235e01e6b42345120b5d270bdb763624c7" };
        var call2 = new Call();
        call2.CallData = balanceOfMessage2.GetCallData();
        call2.Target = "0xc12d1c73ee7dc3615ba4e37e4abfdbddfa38907e";


        var aggregateFunction = new AggregateFunction();
        aggregateFunction.Calls = new List<Call>();
        aggregateFunction.Calls.Add(call1);
        aggregateFunction.Calls.Add(call2);
        //Creating a new query handler
        var queryHandler = web3.Eth.GetContractQueryHandler<AggregateFunction>();

        var returnCalls = await queryHandler
            .QueryDeserializingToObjectAsync<AggregateOutputDTO>(aggregateFunction, "0xeefBa1e63905eF1D7ACbA5a8513c70307C1cE441")
            .ConfigureAwait(false);

        var balance1 = new BalanceOfOutputDTO().DecodeOutput(returnCalls.ReturnData[0].ToHex());
        Console.WriteLine(Web3.Convert.FromWei(balance1.Balance));

        var balance2 = new BalanceOfOutputDTO().DecodeOutput(returnCalls.ReturnData[1].ToHex());
        Console.WriteLine(Web3.Convert.FromWei(balance2.Balance, 8));
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions