Published on

[NeoX Tutorial] Interact with MultiCall contract with Python

Authors

Description

On this article we will see how to interact with MultiCall contract on NeoX blockchain in Python and why could need It.

As an example we will make a simple script allowing us to follow token holding for a list of wallets. Let's say we want a script to query the $WGAS balance for the actual top 10 $WGAS holders.

Retrieving balance for one wallet

If you followed this previous article you already know a way to query some information for a contract. So you can easily adapt to call balanceOf method for a particular wallet.

Difference between NEO N3 and NeoX

We are now able to get the information for one wallet. If we were using NEO N3 we could just build a transaction calling multiple times balanceOf method of the contract. But on EVM chains that's not possible to call multiple contracts in the same transaction. So we will need to send multiple requests requesting the balance for each address of our list if we want to keep requesting $WGAS contract. Hopefully there is another way to do It in EVM chains by calling a MultiCall contract which will allows for the execution of multiple smart contract function calls in a single transaction.

Getting parameters value

For our script we need to gather different information. Let's note that on NeoX chain MultiCall contract is called MultiCall3.

Let's go on documentation page to get the following parameters:

  • RPC endpoint url
  • WGAS contract hash
  • MultiCall3 contract hash

Python code

Now we have all the information we need and we can switch to the coding step. Let's start by installing the web3 Python module we will use for interacting with NeoX using the command pip install web3 and then make the script. We will also use another Python module helping to do the MultiCall formatting by installing w3multicall with this command pip install w3multicall

The code will contains the following parts. The import of the web Python modules:

from web3 import Web3
from w3multicall.multicall import W3Multicall

Then the definition of the variable we retrieved previously and we will use for our call:

WGAS_HASH = "0xdE41591ED1f8ED1484aC2CD8ca0876428de60EfF"
MULTICALL_HASH = "0xD6010D102015fEa9cB3a9AbFBB51994c0Fd6E672"
RPC_URL = "https://mainnet-1.rpc.banelabs.org/"

The list of addresses for which we want to retrieve $WGAS holdings:

ADDRESSES = [
    "0x9955433D475Fd3AeCA02EAcF2A16feFA7dc1b446",
    "0xE1e1cC68841D1fF13bdd8C8fB36E6f91995788f4",
    "0xb30BEA4A784e8544c12f4934E94A230091ebE45B",
    "0x6aa1a0883aba56aB0176aaB83402c50A60506637",
    "0x75326Ca35060d4bB04A414e93DF5544f528B6110",
    "0x2b0e8F0EbE80d97493d09af01279c6f62516CCe9",
    "0x441d81d3F94A4364F23568dF445B618F34634ce3",
    "0x4a45753A6722D9f42ffb4358e7BfbbDb38134c21",
    "0xA51c8Bfcc88A6f9cb80d5D3E644d5DA2c5334C9f",
    "0x9f66B215618814Da23709BF4Fb39F7cC90c0a9A0"
]

Now we can instantiate a Web3 object that will help querying to NeoX chain:

w3 = Web3(Web3.HTTPProvider(RPC_URL))
w3_multicall = W3Multicall(w3, address=MULTICALL_HASH)

We can now create the transaction that will query all balances at once:

for address in ADDRESSES:
    w3_multicall.add(W3Multicall.Call(
            WGAS_HASH,
            'balanceOf(address)(uint256)',
            (
            address
            )
        )
    )

And then send It for getting results:

results = w3_multicall.call()

results object will now contains the list of all our addresses $WGAS balances.

Putting everything together we have the following final script.

from web3 import Web3
from w3multicall.multicall import W3Multicall

WGAS_HASH = "0xdE41591ED1f8ED1484aC2CD8ca0876428de60EfF"
MULTICALL_HASH = "0xD6010D102015fEa9cB3a9AbFBB51994c0Fd6E672"
RPC_URL = "https://mainnet-1.rpc.banelabs.org/"

ADDRESSES = [
    "0x9955433D475Fd3AeCA02EAcF2A16feFA7dc1b446",
    "0xE1e1cC68841D1fF13bdd8C8fB36E6f91995788f4",
    "0xb30BEA4A784e8544c12f4934E94A230091ebE45B",
    "0x6aa1a0883aba56aB0176aaB83402c50A60506637",
    "0x75326Ca35060d4bB04A414e93DF5544f528B6110",
    "0x2b0e8F0EbE80d97493d09af01279c6f62516CCe9",
    "0x441d81d3F94A4364F23568dF445B618F34634ce3",
    "0x4a45753A6722D9f42ffb4358e7BfbbDb38134c21",
    "0xA51c8Bfcc88A6f9cb80d5D3E644d5DA2c5334C9f",
    "0x9f66B215618814Da23709BF4Fb39F7cC90c0a9A0"
]

w3 = Web3(Web3.HTTPProvider(RPC_URL))
w3_multicall = W3Multicall(w3, address=MULTICALL_HASH)

for address in ADDRESSES:
    w3_multicall.add(W3Multicall.Call(
            WGAS_HASH,
            'balanceOf(address)(uint256)',
            (
            address
            )
        )
    )

results = w3_multicall.call()

Conclusion

You now have an example of Python script to interact with MultiCall contract on NeoX blockchain. Feel free to modify It to your own need and to reach me on Discord if you need more help.