Back to homepage

Interact with other contracts using contract Interfaces

Published

One common pattern used in web3 applications and Dapps is interacting between smart contracts of different applications.

Interfaces allow one of our contracts to interact with another contract on the blockchain that we don't own.

For example, image we know the contract below exists in the blockchain and that it's used to store the age of the users by wallet address.

contract UsersAges {
  // stores user's ages by wallet
  mapping(address => uint) ages;

  // public function to save the user's age
  function saveAge(uint _num) public {
    ages[msg.sender] = _num;
  }

  // public function to read the user's age by address
  function getAge(address _myAddress) public view returns (uint) {
    return ages[_myAddress];
  }
}

As you can see, both functions to save and get the user's age (saveAge and getAge) are public, so anyone can call them, for example, another smart contract 😊

Creating a contract Interface

If we wanted to build a separate contract that calls any of the public methods from the contract above, we'll first need to define an interface like this:

// contract interface
contract UsersAgesInterface {
  // function definition of the method we want to interact with
  function getAge(address _myAddress) public view returns (uint);
}

Contract interfaces contain all the methods we want to interact with from the original contract, but instead of having the full code of each function, they only include the function declaration: name, parameters, visivility and value returned. Interfaces do not include the function body.

It's important to note that when creating a smart contract interface, we only need to include the methods we want to interact with. For example, if the original contract has ten different functions but we only want to interact with one of them, our interface will only contains a single method 😉

If you think about it, a function definition is everything we need to interact with other contract. Our contract knows the name of the method, the parameters required and the type of response.

Using a contract interface

In order to actually use a contract interface, there is something else we need to know, the address of the contract we want to interact with.

Then we can create an instance of the contract interface passing the contract address and use it in any of our own contract methods to call the functions defined in the interface.

See an example below:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

// contract interface
contract UsersAgesInterface {
  // function definition of the method we want to interact with
  function getAge(address _myAddress) public view returns (uint);
}

contract AppContract {
  // we need to know the address of the contract we want to interact with
  address UsersAgesContractAddress = 0xabcdef13456abcde...
  // ^ Initialise the interface using the address
  UsersAgesInterface agesContract = UsersAgesInterface(UsersAgesContractAddress);
  // Now `agesContract` is pointing to the other contract address

  function myAppMethod() public  returns (uint){
    // We can call `getAge` from that contract via our interface
    uint age = agesContract.getAge(msg.sender);
    return age
  }
}

In summary, to interact with external contracts we need to know its address, and the public or external methods we want to call. With that information, we can create an interface and use it to actually make those calls from our own smart contract.

Hope you find this article useful ✌️

TAGS

If you enjoyed this article consider sharing it on social media or buying me a coffee ✌️

Buy Me A Coffee