ChainView: a new web3 tool

R3vert
cvgFinance

--

What’s the problematic today ? 🤔

Requesting specific and dependent data from the blockchain is not that easy today. We are only able to request data from existing functions on deployed smart contracts through the explorer in etherscan or through some libraries like ethers. We can also request batched data through some tools like Multicall contracts or batch requests directly through the RPC API.

But the problem is, if you want to request specific data that are dependent on each other you have to wait for the return of the request to get the first batch, to then reuse this data to query another request onchain, to finally get your final response (see schema), boring…

Call dependencies

When the time comes to develop complicated stuff with dependent data, you end up with a messy code that combines multiple multicalls with each other, and you end up struggling to maintain your code or just trying to read it after a period of vacation in Bali with your friends.

And today, in mid-February 2024, while the world is so excited to see the ultra-realistic video made by Sora from OpenAI, we, developers, are still using Multicalls to fetch our data to use it in our Applications, API, indexer, and others programs related to the (EVM) blockchain.

So, for the curious ones who don’t know what we are talking about when we mention Multicall, or for people who just need to refresh their mind, we’ll explain next what a Multicall is and after that what’s the answer of the following question:

Why the fuck it’s so hard to retrieve complex or dependent data onchain, and how can I retrieve it easily ?

What’s a Call ? 📞

To understand what a Multicall is, you first need to understand what a blockchain call is. There are 2 types of call:

  • First type for “read” that will allow us to read public data from a smart contract
  • Second type for “write” that will allow us to change the state of the blockchain, such as changing some data in a smart contract or deploying a new smart contract.

Here, for simplicity we will only talk about calls that read data from the blockchain.

So, for example a call can be the function “balanceOf” of the WETH contract for your address that is used by your favorite wallet provider or Dapp to know what’s your balance and what to do with it.

BalanceOf function for WETH token in etherscan

When you call it, you will request through the RPC API the data from the WETH contract corresponding to the mapping balanceOf(address) that will returns to you (after a tiny waiting time) your balance in wei units. So you call it, you wait and you get your data, that’s COOL.

BalanceOf function for WETH token in etherscan, with the result for an address

What‘s a Multicall ? 📝

A Multicall is the same as a Call, but it allows us to call not a single balanceOf for one address but for multiple addresses in just ONE call, pretty cool nah ?

To do this, you will need to use the Multicall contract, which is a smart contract deployed on the blockchain and very simple in its implementation.

Aggregate function of the Multicall2 contract
Call structure parameter for aggregate function

To summarize the function, it simply needs as a parameter, an array of the call you want to pass through the multicall. The struct “Call” is a combination of the “target” contract to call and “callData” the encoded function+parameters to call in the given contract. So each index of the array parameter correspond to one specific call.

For example, if you want to retrieve the WETH balanceOf of address1 and address2, you’ll simply need to pass in the “aggregate()” function the parameters:

Multicall structuration

And, in return the multicall contract will give you the two balances requested in one call.

So, multicall seems to works correctly and even with a lot of request on it you will get your result without a lot of problems.

YES, BUT…

Problem with Multicall 😩

Imagine if you have two function calls to request from your magic multicall contract , but these data seem to be dependent on each other. This means that you need the first result call, then use it to call the second function to get the final data.

Let’s take an example with a NFT(ERC721) collection.

You want to know who is the owner of the first NFT of the collection and how many NFTs the owner has in the same collection.

You will want to retrieve from the function “ownerOf(tokenId)” the owner address and from the function “balanceOf(address)” the number of ids he owns. But you cannot request them in the same time because you need to get the response of the first “ownerOf” function to get the address used in the “balanceOf” function.

So batching with multicall is impossible and you have to make two separate calls to get the final data.

And that’s the point, we’re stuck with this problem today. Multi-dependent calls are a mess in the blockchain and the only known way to get around it, is to deploy a smart contract with some specific function to retrieve specific information. But at the end you need to pay some ETH to deploy your contract, and redeploy it if you need to modify some specificities in your function. So just burn your ETH to retrieve your information?

NO WAY!

There is an another way to get specific and dependent datas and all of that FOR FREE !

This way is called ChainView, it’s a tool that you can use to get all the data you want, even if the data are dependent or not. The only limitation is the gas and the timeout of the RPC you are requesting your data from.

So the next question is…

What is ChainView & How to use it ?👀

As we said, ChainView allows us this time to retrieve dependent data in a simple ONE call, without paying any fees to anyone.

But how is this possible ?

In the previous point we concluded that the only way to get dependent data in one call is to deploy a specific smart contract to retrieve specific data. So, we used this assumption plus some tricks into the EVM (Ethereum Virtual Machine) to get our finalized tool named ChainView.

The trick is simple, we compile the Solidity code and simulate a deployment to retrieve the information we want.

This tool is not complex as it seems, and it basically need two things:

  • Solidity code containing the logic you want to use to retrieve your specific data
  • ChainView function

With this, you can by following the next steps, get your precious data.

To illustrate the steps let’s take the last example where the multicall failed:

Let’s take an example with a NFT(ERC721) collection.

You want to know who is the owner of the first NFT of the collection and how many NFT’s of this same collection the owner has.

0. Install ChainView

In a new repository use this command to install ChainView:

npm i chainview

1. Create your logic

You will need to write the function into a new Solidity contract that will retrieve the data you want.

Contract logic implementation basis (copy code here)

And then add, a Custom Error at the end of the function, plus finally create a Constructor calling this function.

Contract logic implementation with constructor/error to be compatible with ChainView (copy code here)

2. Compile your code

Your smart contract wants to be in a folder named “Chainview”, to be compiled using the command:

npx chainview compile

A new folder is created named “chainviewArtifacts” that contains the ABI and bytecode of your smart contract.

3. Call ChainView

Through a JavaScript script, you can now call the ChainView function like that:

JavaScript script implementation of ChainView (copy code here)

Or through a TypeScript script:

TypeScript script implementation of ChainView (copy code here)

To obtain the desired data:

logs result

4. And…Voilà 🎉

Finally, you can see that it is possible to get chained data in a simple call, and without much complexity. All you need to know is to code in Solidity.

Now let’s compare it with Multicall.

ChainView vs Multicall (example with code) 💥

Here we will compare the implementation code between ChainView and Multicall. In this example, we will only use non-dependent data in order to have a fair comparison between the two methods.

We want to know the balance of WETH token for 2 holders

With Multicall

Script:

JavaScript script implementation of multicall with this example below (copy code here)

Output:

Multicall response logs

With ChainView

Solidity:

Solidity/ChainView implementation for the example below (copy code here)

Script:

JavaScript/ChainView implementation for the example below (copy code here)

Output:

ChainView response logs

So, we can see in this example that the multicall implementation is shorter than ChainView implementation and only needs a single script to retrieve the desired data. The owner address is not returned by the multicall because we are only calling the balanceOf function, so we need to associate with the corresponding address after the call. You will need to check in your code that addresses are associated to their corresponding returned data.

For ChainView it’s a bit longer, clearer to understand, and the logic is well separated from the script. We can also see that balances are directly associated to their address. So you don’t have to check again after the call. It’s safer that way.

Pros and Cons 📊

Multicall

Pros 🟢

  • Can batch a lot of call very easily and quickly
  • Use only one language

Cons 🔴

  • Not able to call batch of dependent data
  • Cannot structurate and perzonalize the returned data

ChainView

Pros 🟢

  • Can call batches of independent & dependent data
  • Able to structure and personalize the returned data
  • Clean and secure your code by giving all the logic reponsibilities to the Solidity contract
  • Can simulate real transactions (write mode)

Cons 🔴

  • Use at least 2 languages
  • Bit longer to implement / write than Multicall

Conclusion

In this article, we saw that the problem for EVM developers today is that we cannot get multi-dependent information from the blockchain in a simple way. We explained the use of the Multicall, which is not optimized for this kind of calls.

Then we saw that ChainView can solve this problem and can also be used more efficiently in some cases. We compared the implementation of these two methods and saw that Multicall and ChainView can be implemented for different uses depending on your needs. So these two tools can easily be used in pairs.

ChainView, will also clean up and even secure your code because we separate the logic between Solidity and your script. Also, giving the logic responsibilities to the Solidity contract will give you less side effects on your returned responses.

We, at Convergence Finance, have used ChainView in our Indexer, Dapp and API to optimize our calls, and we have actually seen some good results compared to the classic way. We are happy to share this with the community, and hope it will help developers in their projects.

You are now able to retrieve a lot of chained data on the blockchain to build your projects (Dapps,API,Indexer,Bots,Dashboard,…). And keep in mind that we only discussed about “read” calls, you are also able to use and simulate “write” calls with ChainView. 🥸

So now, let’s use your imagination to maybe find some interesting things down the rabbit hole anons… 🐇

Ressources 📚

https://github.com/Cvg-Finance/ChainView

https://soliditylang.org/blog/2021/04/21/custom-errors/

https://cvg.finance/

https://github.com/ethers-io/ethers.js

--

--