7 OpenZeppelin Contracts You Should Always Use
OpenZeppelin’s smart contract repository is an invaluable resource for Ethereum developers. It has community-vetted implementations of ERC token standards, security protocols, and other utilities that enable developers to focus on functionality, reducing the need to reinvent the wheel.
“A library for secure smart contract development. Build on a solid foundation of community-vetted code.” — OpenZeppelin.com
Here’s a list of the most useful Openzeppelin smart contracts you should be using in your projects.
Note: In this article, we’re using OpenZeppelin contracts version 2.5.x, where all contracts are compiled using solidity compiler version 0.5.x.
onlyOwner pattern provided by the
Ownable contract is a primitive but highly effective pattern for restricting access to certain functions. This makes it a very popular choice for smart contract developers.
It implements the premise that the address that deployed the smart contract is its owner. Certain functions, like transferring ownership, should only be allowed to be called from the owner's address.
Figure 1 shows the
Notice how setting the owner of the contract is handled by the constructor on line 23. As soon as any child contract is initialized, the address which initializes it will, by default, become the
Figure 2 shows a simple implementation of extending the
By adding the
onlyOwner custom modifier to
restrictedFunction(), only the owner of the contract can successfully call it.
The next level up from
Ownable is the
Roles library, which allows more than just one owner role to be implemented. This is handy when a contract has functions for multiple access levels.
Figure 3 shows the
Being a library, you can’t extend it as you would an abstract contract. Instead, contracts using this library use a
using statement to declare that the functions provided by the library be used for a specific data type.
For example, figure 4 shows a contract which uses the
Roles library to restrict functions to two roles:
Line 8 declares that this contract must use the
Roles library for any operations that occur on
Roles.Role data types. Line 18 shows this being used in
add() being a function provided by the
Never write mathematic calculations using bare arithmetic operators like plus, minus, divide, and multiply. Unless you specifically check for under and overflow vulnerabilities, you can’t guarantee the calculations will be safe.
This is where
SafeMath comes in. It performs all the required checks you need to be confident that your calculations run correctly, without introducing vulnerabilities to your code.
Figure 5 shows the
Use this library the same way you’d use the
Roles library, by declaring unit operations to be performed by
SafeMath with a
using statement. This can be seen in figure 6, on line 7. Line 10 shows the usage of the
SafeMath library to perform subtraction.
As a smart contract developer, you should always be looking to save execution time and space. One way to save space is to use smaller sizes for integer data types. Unfortunately, if you’re using
uint8 for a variable and want to do some
SafeMath on it, you have to cast it up to
uint256). If you want the result back in
uint8 again, you have to cast it back.
SafeCast enables you to do this without worrying about overflow issues.
Figure 7 shows the
Figure 8 shows a basic implementation using the
SafeCast library, casting
uint to a
Don’t even think about writing a full
ERC20 contract — OpenZeppelin has already done it for you. All you need to do is extend it and initialize it, the rest of the code is already done.
There are other options to choose from. For example, the basic
ERC20 contract that OpenZeppelin provides is fine as long as you don’t need to name your token.
ERC20Detailed has the added functionality to name it, provide a symbol, and the number of decimal places it has.
Figure 9 shows how easy it is to write an ERC20 token using
6. ERC721Enumerable & ERC721Full
The same goes for
ERC721, non-fungible tokens. You just don’t need to write a contract that conforms to the standard when it’s already been done.
ERC721Enumberable instead of the basic
ERC721 to make retrieving all the tokens that an address owns easier by calling
_tokensOfOwner(address owner). Or, if you want all the bells and whistles, the
ERC721Full contract comes with every additional extension. Figure 10 shows the implementation of
It’s difficult to know whether an address your smart contract is dealing with is an actual wallet or another smart contract. The
Address contract provides a function called
isContract() which returns a boolean answering that very question.
Figure 11 shows how to use
If you’re interested in blockchain development, I write tutorials, walkthroughs, hints, and tips on how to get started and build a portfolio. Check out some of these resources: