Solidity override vs. virtual functions

In our most recent smart contract project, we used Solidity 0.6 where I learned about vs . As always, you can read the docs, but I wanted to write this post for those of us who prefer to read quick tutorials on Medium.

Solidity is an object-oriented programming language that supports multiple inheritances. You can inherit from a base contract and then override a function in that base contract. Before Solidity 0.6, there was no way of knowing what functions should be overridden. Now, you can explicitly label a function as or .

Function Overriding

A function that allows an inheriting contract to override its behavior will be marked at . The function that overrides that base function should be marked as . Let’s take a look at an example from our favorite library, OpenZeppelin.

If you look at the ERC20.sol contract in the latest version of the library you will see that the function contains both the and keywords.

function transfer(address recipient, uint256 amount) public virtual override returns (bool) {      _transfer(_msgSender(), recipient, amount);
return true;
}

This means if you inherit the ERC20.sol contract into your project, you can write your own function and mark it as since it’s overriding the base function. If you forget to add the the compiler will yell at you:

TypeError: Overriding function is missing "override" specifier.

The reason the OpenZeppelin function includes the keyword is because it’s inheriting the IERC20 interface which also has a function. All functions in interface contracts are automatically considered .

If your contract is inheriting the same function from multiple base contracts (that are unrelated), you must explicitly state which contracts:

pragma solidity >=0.5.0 <0.7.0;

contract Base1
{
function foo() virtual public {}
}

contract Base2
{
function foo() virtual public {}
}

contract Inherited is Base1, Base2
{
// Derives from multiple bases defining foo(), so we must explicitly
// override it
function foo() public override(Base1, Base2) {}
}

Conclusion

That’s it, folks! This update makes it clear what functions are meant to be overridden vs what functions should be left as is. This is useful when working with libraries such as OpenZeppelin. This is also useful if you are building a contract that is meant to be used by other developers. You can be explicit in your intention for a function. If you do not want a function to be overridden, leave off the marker.

Upstate Interactive is a software consultancy that builds custom web and mobile applications and decentralized applications. If you need help with your smart contract application, please email us at team@upstateinteractive.io 💜

☞ Follow us on Medium, Twitter, and LinkedIn

☞ Follow me on Twitter @devgirlla

☞ Sign up for our monthly newsletter below

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store