multicall

package module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 25, 2024 License: MIT Imports: 11 Imported by: 0

README

go-multicall

A Go library for efficient Ethereum multicalls using the Multicall3 contract.

Features

  • Efficient batching of multiple contract calls
  • Support for different Ethereum networks
  • Configurable batch size and timeout
  • Error handling and failed call detection
  • Allow failure of calls using Aggregate3

Installation

To install go-multicall, use the following command:

go get github.com/NotCoffee418/go-multicall

Usage

Here's a basic example of how to use go-multicall to fetch multiple ERC20 token names in a single call:

package main

import (
	"fmt"
	"log"
	"strings"
	"time"

	"github.com/NotCoffee418/go-multicall"
	"github.com/ethereum/go-ethereum/accounts/abi"
	"github.com/ethereum/go-ethereum/common"
	"github.com/ethereum/go-ethereum/ethclient"
)

func main() {
	// Connect to an Ethereum node
	client, err := ethclient.Dial("https://polygon-rpc.com/")
	if err != nil {
		log.Fatalf("Failed to connect to the Ethereum client: %v", err)
	}

    // Multicall3 for your your chain
    // Find it here: https://www.multicall3.com/deployments
    multicallAddress := common.HexToAddress("0xcA11bde05977b3631167028862bE2a173976CA11")

	// Create a multicall configuration
	cfg := multicall.NewMulticallConfig(
		client,
		multicallAddress, 
		100,  // Batch size
		30*time.Second, // Timeout
	)

	// Load the target contract abi
	erc20ABI, err := abi.JSON("[]") // Placeholder
	if err != nil {
		log.Fatalf("Failed to parse ABI: %v", err)
	}

	// Define token addresses to query
	tokenAddresses := []common.Address{
		common.HexToAddress("0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619"), // WETH
		common.HexToAddress("0xc2132D05D31c914a87C6611C10748AEb04B58e8F"), // USDT
		common.HexToAddress("0x3BA4c387f786bFEE076A58914F5Bd38d668B42c3"), // BNB
	}

	// Prepare multicall requests
	requests := make([]multicall.CallRequest, len(tokenAddresses))
	for i, addr := range tokenAddresses {
		callData, err := erc20ABI.Pack("name")
		if err != nil {
			log.Fatalf("Failed to pack call data: %v", err)
		}
		requests[i] = multicall.NewCallRequest(addr, callData, true)
	}

	// Execute multicall
	results, err := multicall.MulticallRaw(cfg, requests)
	if err != nil {
		log.Fatalf("Multicall failed: %v", err)
	}

	// Process results
	for i, result := range results {
		if result.Success {
			name, err := erc20ABI.Unpack("name", result.Data)
			if err != nil {
				log.Printf("Failed to unpack result for %s: %v", tokenAddresses[i].Hex(), err)
				continue
			}
			fmt.Printf("Token at %s has name: %s\n", tokenAddresses[i].Hex(), name[0].(string))
		} else {
			fmt.Printf("Call failed for token at %s\n", tokenAddresses[i].Hex())
		}
	}
}

This example demonstrates how to:

  1. Connect to an Ethereum node (Polygon in this case)
  2. Create a multicall configuration
  3. Prepare ERC20 'name' function calls for multiple token addresses
  4. Execute the multicall
  5. Process and display the results

Dependencies

License

MIT License

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type CallRequest

type CallRequest struct {
	Target       common.Address
	AllowFailure bool
	CallData     []byte
}

CallRequest is a packed call to be executed with multicall. ABI Definition: Call3

Parameters:

  • Target: The address of the contract to call
  • AllowFailure: Whether the call is allowed to fail
  • CallData: packed calldata to the target contract with abi.Pack

func NewCallRequest

func NewCallRequest(
	target common.Address,
	packedCallData []byte,
	allowFailure bool,
) CallRequest

type CallResult

type CallResult struct {
	Success bool
	Data    []byte
}

CallResult is the packedresult of a packed call executed with multicall. ABI Definition: Call3Value

Parameters:

  • Data: Packed result of the call. Unpacked with abi.Unpack
  • Success: Whether the call was successful

func MulticallRaw

func MulticallRaw(
	cfg *MulticallConfig,
	calls []CallRequest,
) ([]CallResult, error)

MulticallRaw allows you to multicall directly with abi packed calls. Allows various functions on various contracts. Recommended function for most control and best performance.

Parameters:

  • cfg: The multicall config to use
  • calls: The calls to execute.

Returns:

  • []CallResult: Packed results and success status of the calls
  • error: An error if the multicall fails

type MulticallConfig

type MulticallConfig struct {
	Client           *ethclient.Client
	MulticallAddress common.Address
	BatchSize        int
	Timeout          time.Duration
}

MulticallConfig is a reusable multicall config.

Parameters:

  • Client: The Ethereum client to use
  • MulticallAddress: The address of the multicall contract for the chain. You can find the deployment address for your chain at https://www.multicall3.com/deployments
  • BatchSize: The maximum number of calls to include in a single multicall Generally it's cheaper and faster to pack as many calls as possible in a single multicall. Default: 100
  • Timeout: The timeout for the multicall. Default: 30 seconds

func NewDefaultMulticallConfig

func NewDefaultMulticallConfig(client *ethclient.Client, multicallAddress common.Address) *MulticallConfig

Create a new reusable multicall config

Parameters:

  • client: The Ethereum client to use
  • multicallAddress: The address of the multicall contract for the chain. You can find the deployment address for your chain at https://www.multicall3.com/deployments

func NewMulticallConfig

func NewMulticallConfig(
	client *ethclient.Client,
	multicallAddress common.Address,
	batchSize int,
	timeout time.Duration,
) *MulticallConfig

Create a new reusable multicall config

Parameters:

  • client: The Ethereum client to use
  • multicallAddress: The address of the multicall contract for the chain. You can find the deployment address for your chain at https://www.multicall3.com/deployments
  • batchSize: The maximum number of calls to include in a single multicall Generally it's cheaper and faster to pack as many calls as possible in a single multicall. Default: 100

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL