7 OpenZeppelin Contracts You Should Always Use

Improve your smart contract development with OpenZeppelin

Alex Roan
Alex Roan
Apr 23 · 4 min read
Image for post
Image for post
OpenZeppelin Logo

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

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.

Controlling Access

1. Ownable

The 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 Ownable contract.

Figure 1: Ownable contract

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 _owner.

Figure 2 shows a simple implementation of extending the Ownable contract:

Figure 2: Ownable Contract

By adding the onlyOwner custom modifier to restrictedFunction(), only the owner of the contract can successfully call it.

2. Roles

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 Roles library.

Figure 3: Roles.sol

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: _minters and _burners.

Figure 4: Using 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 _minters.add() add() being a function provided by the Roles library.

Arithmetic

3. SafeMath

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 SafeMath library.

Figure 5: SafeMath library

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.

Figure 6: Using SafeMath

4. SafeCast

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 uint (AKA 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 SafeCast library.

Figure 8 shows a basic implementation using the SafeCast library, casting uint to a uint8 datatype.

Figure 8: Using SafeCast

Tokens

5. ERC20Detailed

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 ERC20 and ERC20Detailed contracts.

Figure 9: Custom ERC20 Token

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.

Use the 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 ERC721Full.

Figure 10: Full ERC721

Utilities

7. Address

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 isContract().

Further Reading

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:

Better Programming

Advice for programmers.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

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