Interact with other contracts using contract Interfaces
Published
Table of contents
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