Solidity: call smart contract from another smart contract

In this blog, let us see how to use a smart contract in our main smart contract. If you are a Solidity developer, a situation to use another contract or library will come sooner or later due to Solidity size limitations. And based on requirements like to use information from another smart contract.

Smart Contract Size Limitation

On November 22, 2016, as part of the Spurious Dragon Fork, Ethereum introduced this limitation of restricting the smart contract size to 24576 Bytes also known as EIP-170.

Why this is done?

  • To prevent Denial of service to other uses as one large contract may utilize many resources potentially causing DOS.
  • Another reason is the block's gas limit. When we deploy a contract, its bytecode must fit in a single transaction.

How to find out Smart Contract size?

  • One way is not to get the below error.

Warning: Contract code size exceeds 24576 bytes (a limit introduced in Spurious Dragon). This contract may not be deployable on Mainnet. Consider enabling the optimizer (with a low "runs" value!), turning off revert strings, or using libraries.

  • Another way is to install a truffle contract size plugin. I have attached a resource on how to use this plugin at the end.
npm install truffle-contract-size

Using Smart Contract in Another Contract

Let us define a contract. For Example, let us create a whitelist contract to whitelist user addresses.

Now, this same contract can be used in the NFT presale to allow whitelisted users to mint NFTs in a presale or we can give them an Initial coin offering. 

Let us keep our main contract simple. Assume we have a contract that adds numbers. Everyone can add only less than number 5. Whitelisted users can add up to number 10.

Before writing the contract, we need to understand a bit about interfaces. Interfaces are like abstract contracts and they do not contain any implementation. They do not have state variables or constructors.

Let us create an interface IWhitelist with interface keyword and it contains only one function which returns the whitelisted addresses. We have whitelistedAddresses public state variable in the above contract, so a function is provided by default.

Why we are creating an interface and using only one function?

This way, we would save gas fees by not importing all the functionality from the Whitelist contract which we don’t require.

While deploying the contract on Remix, mention the already deployed WhiteList contract address.


Explaining the Smart Contract

This contract takes the address of WhiteList contract in the constructor and assigns it to IWhiteList interface which will enable fetching the whitelist addresses stored in the WhiteList contract.

We have an amount variable and addAmount function with single argument amt.

Any user can interact with this function by providing a number for amt argument.

As mentioned previously, this contract checks

  • If a non-whitelisted user is interacting, amt should be less than or equal to 5. If not, this will throw an error "Non Whitelisted addresses can add only up to 5" and the transaction will fail.
  • If a whitelisted user is interacting, it will check for amt less than or equal to 10 else the transaction will fail with the error "Whitelisted addresses can add only up to 10"

The contract also contains getAmount function to fetch the amount added so far.

We can also reuse the WhiteList contract by inheriting it and I will explain inheritance in a detailed manner in another blog.

Resources

Post a Comment

Previous Post Next Post