multicall

package module
v0.0.0-...-9467c4d Latest Latest
Warning

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

Go to latest
Published: Jul 1, 2023 License: MIT Imports: 11 Imported by: 9

README

go-multicall

coverage build

A thin Go client for making multiple function calls in single eth_call request

Warning: MakerDAO Multicall contracts are different than the OpenZeppelin Multicall contract. Please see this thread in the OpenZeppelin forum if you are looking for an explanation.

Install

go get github.com/forta-network/go-multicall

Example

(See other examples under the examples directory!)

package main

import (
	"context"
	"fmt"
	"math/big"

	"github.com/forta-network/go-multicall"
	"github.com/ethereum/go-ethereum/common"
)

const (
	APIURL   = "https://cloudflare-eth.com"
	ERC20ABI = `[
		{
			"constant":true,
			"inputs":[
					{
						"name":"tokenOwner",
						"type":"address"
					}
			],
			"name":"balanceOf",
			"outputs":[
					{
						"name":"balance",
						"type":"uint256"
					}
			],
			"payable":false,
			"stateMutability":"view",
			"type":"function"
		}
	]`
)

type balanceOutput struct {
	Balance *big.Int
}

func main() {
	caller, err := multicall.Dial(context.Background(), APIURL)
	if err != nil {
		panic(err)
	}

	contract, err := multicall.NewContract(ERC20ABI, "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48")
	if err != nil {
		panic(err)
	}

	calls, err := caller.Call(nil,
		contract.NewCall(
			new(balanceOutput),
			"balanceOf",
			common.HexToAddress("0xcEe284F754E854890e311e3280b767F80797180d"), // Arbitrum One gateway
		).Name("Arbitrum One gateway balance"),
		contract.NewCall(
			new(balanceOutput),
			"balanceOf",
			common.HexToAddress("0x40ec5B33f54e0E8A33A975908C5BA1c14e5BbbDf"), // Polygon ERC20 bridge
		).Name("Polygon ERC20 bridge balance"),
	)
	if err != nil {
		panic(err)
	}
	for _, call := range calls {
		fmt.Println(call.CallName, ":", call.Outputs.(*balanceOutput).Balance)
	}
}

Documentation

Index

Constants

View Source
const DefaultAddress = "0xcA11bde05977b3631167028862bE2a173976CA11"

DefaultAddress is the same for all chains (Multicall3). Taken from https://github.com/mds1/multicall

Variables

This section is empty.

Functions

func ParseABI

func ParseABI(rawJson string) (*abi.ABI, error)

ParseABI parses raw ABI JSON.

Types

type Call

type Call struct {
	CallName string
	Contract *Contract
	Method   string
	Inputs   []any
	Outputs  any
	CanFail  bool
	Failed   bool
}

Call wraps a multicall call.

func (*Call) AllowFailure

func (call *Call) AllowFailure() *Call

AllowFailure sets if the call is allowed to fail. This helps avoiding a revert when one of the calls in the array fails.

func (*Call) Name

func (call *Call) Name(name string) *Call

Name sets a name for the call.

func (*Call) Pack

func (call *Call) Pack() ([]byte, error)

Pack converts and packs EVM inputs.

func (*Call) Unpack

func (call *Call) Unpack(b []byte) error

Unpack unpacks and converts EVM outputs and sets struct fields.

type Caller

type Caller struct {
	// contains filtered or unexported fields
}

Caller makes multicalls.

func Dial

func Dial(ctx context.Context, rawUrl string, multicallAddr ...string) (*Caller, error)

Dial dials and Ethereum JSON-RPC API and uses the client as the caller backend.

func New

func New(client bind.ContractCaller, multicallAddr ...string) (*Caller, error)

New creates a new caller.

func (*Caller) Call

func (caller *Caller) Call(opts *bind.CallOpts, calls ...*Call) ([]*Call, error)

Call makes multicalls.

func (*Caller) CallChunked

func (caller *Caller) CallChunked(opts *bind.CallOpts, chunkSize int, cooldown time.Duration, calls ...*Call) ([]*Call, error)

CallChunked makes multiple multicalls by chunking given calls. Cooldown is helpful for sleeping between chunks and avoiding rate limits.

type Contract

type Contract struct {
	ABI     *abi.ABI
	Address common.Address
}

Contract wraps the parsed ABI and acts as a call factory.

func NewContract

func NewContract(rawJson, address string) (*Contract, error)

NewContract creates a new call factory.

func (*Contract) NewCall

func (contract *Contract) NewCall(
	outputs any, methodName string, inputs ...any,
) *Call

NewCall creates a new call using given inputs. Outputs type is the expected output struct to unpack and set values in.

Directories

Path Synopsis
contracts
examples

Jump to

Keyboard shortcuts

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