Contract Wizard

Using OpenZeppelin Contracts and Remix To Deploy To Phron

Introduction

OpenZeppelin contracts and libraries have become a standard in the industry. They help developers minimize risk, as their open-source code templates are battle-tested for Ethereum and other blockchains. Their code includes the most used implementations of ERC standards and add-ons and often appears in guides and tutorials around the community.

Because Phron is fully Ethereum compatible, all of OpenZeppelin's contracts and libraries can be implemented without any changes.

This guide is divided into two sections. The first part describes the OpenZeppelin Contracts Wizard, a great online tool to help you create smart contracts using OpenZeppelin code. The second section provides a step-by-step guide on how you can deploy these contracts using Remix on Phron.

OpenZeppelin Contract Wizard

OpenZeppelin has developed an online web-based interactive contract generator tool that is probably the easiest and fastest way to write your smart contract using OpenZeppelin code, called Contracts Wizard.

Currently, the Contracts Wizard support the following ERC standards:

  • ERC-20 — a fungible token standard that follows EIP-20. Fungible means that all tokens are equivalent and interchangeable that is, of equal value. One typical example of fungible tokens is fiat currencies, where each equal-denomination bill has the same value

  • ERC-721 — a non-fungible token contract that follows EIP-721. Non-fungible means that each token is different, and therefore, unique. An ERC-721 token can represent ownership of that unique item, whether it is a collectible item in a game, real estate, and so on

  • ERC-1155 — also known as the multi-token contract, because it can represent both fungible and non-fungible tokens in a single smart contract. It follows EIP-1155

The wizard is comprised of the following sections:

  1. Token standard selection — shows all the different standards supported by the wizard

  2. Settings — provides the baseline settings for each token standard, such as token name, symbol, pre-mint (token supply when the contract is deployed), and URI (for non-fungible tokens)

  3. Features — list of all features available for each token standard. You can find more information about the different features in the following links:

  4. Access Control — list of all the available access control mechanisms for each token standard

  5. Interactive code display — shows the smart contract code with the configuration as set by the user

Once you have set up your contract with all the settings and features, it is just as easy as copying and pasting the code into your contract file.

Deploying OpenZeppelin Contracts on Phron

This section goes through the steps for deploying OpenZeppelin contracts on Phron. It covers the following contracts:

  • ERC-20 (fungible tokens)

  • ERC-721 (non-fungible tokens)

  • ERC-1155 (multi-token standard)

All the code of the contracts was obtained using OpenZeppelin Contract Wizard.

Checking Prerequisites

The steps described in this section assume you have MetaMask installed and connected to the Phron TestNet. If you're adapting this guide for Phron, make sure you're connected to the correct network. Contract deployment is done using the Remix IDE via the Injected Provider environment. You can find corresponding tutorials in the following links:

  • Interacting with Phron using MetaMask

  • Interacting with Phron using Remix

Deploying an ERC-20 Token

For this example, an ERC-20 token will be deployed to Phron. The final code used combines different contracts from OpenZeppelin:

  • ERC20.sol — ERC-20 token implementation with the optional features from the base interface. Includes the supply mechanism with a mint function but needs to be explicitly called from within the main contract

  • Ownable.sol — extension to restrict access to certain functions

The mintable ERC-20 OpenZeppelin token contract provides a mint function that the owner of the contract can only call. By default, the owner is the contract's deployer address. There is also a premint of 1000 tokens sent to the contract's deployer configured in the constructor function.

The first step is to go to Remix and take the following steps:

  1. Click on the Create New File icon and set a file name. For this example, it was set to ERC20.sol

  2. Make sure the file was created successfully. Click on the file to open it up in the text editor

  3. Write your smart contract using the file editor. For this example, the following code was used:

// SPDX-License-Identifier: MIT
// Compatible with OpenZeppelin Contracts ^5.0.0
pragma solidity ^0.8.20;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Permit.sol";

contract MyToken is ERC20, Ownable, ERC20Permit {
    constructor(address initialOwner)
        ERC20("MyToken", "MTK")
        Ownable(initialOwner)
        ERC20Permit("MyToken")
    {
        _mint(msg.sender, 1000 * 10 ** decimals());
    }

    function mint(address to, uint256 amount) public onlyOwner {
        _mint(to, amount);
    }
}

This ERC-20 token smart contract was extracted from the Contract Wizard, setting a premint of 1000 tokens and activating the Mintable and Permit features.

Once your smart contract is written, you can compile it by taking the following steps:

  1. Head to the Solidity Compiler

  2. Click on the compile button

  3. Alternatively, you can check the Auto compile feature

With the contract compiled, you are ready to deploy it taking the following steps:

  1. Head to the Deploy & Run Transactions tab

  2. Change the environment to Injected Provider. This will use MetaMask's injected provider. Consequently, the contract will be deployed to whatever network MetaMask is connected to. MetaMask might show a pop-up outlining that Remix is trying to connect to your wallet

  3. Select the proper contract to deploy. In this example, it is the MyToken contract inside the ERC20.sol file

  4. Enter the address of the initial owner and click on the Deploy button. Review the transaction information in MetaMask and confirm it

  5. After a few seconds, the transaction should get confirmed, and you should see your contract under Deployed Contracts

And that is it! You've deployed an ERC-20 token contract using OpenZeppelin's contracts and libraries. Next, you can interact with your token contract via Remix, or add it to MetaMask.

Deploying an ERC-721 Token

For this example, an ERC-721 token will be deployed to Phron. The final code used combines different contracts from OpenZeppelin:

  • ERC721.sol — ERC-721 token implementation with the optional features from the base interface. Includes the supply mechanism with a _mint function but needs to be explicitly called from within the main contract

  • ERC721Burnable.sol — extension to allow tokens to be destroyed by their owners (or approved addresses)

  • ERC721Enumerable.sol — extension to allow on-chain enumeration of tokens

  • Ownable.sol — extension to restrict access to certain functions

The mintable ERC-721 OpenZeppelin token contract provides a mint function that can only be called by the owner of the contract. By default, the owner is the contract's deployer address.

As with the ERC-20 contract, the first step is to go to Remix and create a new file. For this example, the file name will be ERC721.sol.

Next, you'll need to write the smart contract and compile it. For this example, the following code is used:

// SPDX-License-Identifier: MIT
// Compatible with OpenZeppelin Contracts ^5.0.0
pragma solidity ^0.8.20;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

contract MyToken is ERC721, ERC721Enumerable, ERC721Burnable, Ownable {
    constructor(address initialOwner)
        ERC721("MyToken", "MTK")
        Ownable(initialOwner)
    {}

    function _baseURI() internal pure override returns (string memory) {
        return "Test";
    }

    function safeMint(address to, uint256 tokenId) public onlyOwner {
        _safeMint(to, tokenId);
    }

    // The following functions are overrides required by Solidity
    function _update(address to, uint256 tokenId, address auth)
        internal
        override(ERC721, ERC721Enumerable)
        returns (address)
    {
        return super._update(to, tokenId, auth);
    }

    function _increaseBalance(address account, uint128 value)
        internal
        override(ERC721, ERC721Enumerable)
    {
        super._increaseBalance(account, value);
    }

    function supportsInterface(bytes4 interfaceId)
        public
        view
        override(ERC721, ERC721Enumerable)
        returns (bool)
    {
        return super.supportsInterface(interfaceId);
    }
}

This ERC-721 token smart contract was extracted from the Contract Wizard, setting the Base URI as Test and activating the Mintable, Burnable, and Enumerable features.

With the contract compiled, next you will need to:

  1. Head to the Deploy & Run Transactions tab

  2. Change the environment to Injected Provider. This will use MetaMask's injected provider. Consequently, the contract will be deployed to whatever network MetaMask is connected to. MetaMask might show a pop-up outlining that Remix is trying to connect to your wallet

  3. Select the proper contract to deploy. In this example, it is the MyToken contract inside the ERC721.sol file

  4. Enter the address of the initial owner and click on the Deploy button. Review the transaction information in MetaMask and confirm it

  5. After a few seconds, the transaction should get confirmed, and you should see your contract under Deployed Contracts

And that is it! You've deployed an ERC-721 token contract using OpenZeppelin's contracts and libraries. Next, you can interact with your token contract via Remix, or add it to MetaMask.

Deploying an ERC-1155 Token

For this example, an ERC-1155 token will be deployed to Phron. The final code used combines different contracts from OpenZeppelin:

  • ERC1155.sol — ERC-1155 token implementation with the optional features from the base interface. Includes the supply mechanism with a _mint function but needs to be explicitly called from within the main contract

  • Pausable.sol — extension to allows pausing tokens transfer, mintings and burnings

  • Ownable.sol — extension to restrict access to certain functions

OpenZeppelin's ERC-1155 token contract provides a _mint function that can only be called in the constructor function. Therefore, this example creates 1000 tokens with an ID of 0, and 1 unique token with an ID of 1.

The first step is to go to Remix and create a new file. For this example, the file name will be ERC1155.sol.

As shown for the ERC-20 token, you'll need to write the smart contract and compile it. For this example, the following code is used:

// SPDX-License-Identifier: MIT
// Compatible with OpenZeppelin Contracts ^5.0.0
pragma solidity ^0.8.20;

import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC1155/extensions/ERC1155Pausable.sol";

contract MyToken is ERC1155, Ownable, ERC1155Pausable {
    constructor() ERC1155("") Ownable() {
        _mint(msg.sender, 0, 1000 * 10 ** 18, "");
        _mint(msg.sender, 1, 1, "");
    }

    function setURI(string memory newuri) public onlyOwner {
        _setURI(newuri);
    }

    function pause() public onlyOwner {
        _pause();
    }

    function unpause() public onlyOwner {
        _unpause();
    }

    // The following function is an override required by Solidity
    function _update(address from, address to, uint256[] memory ids, uint256[] memory values)
        internal
        override(ERC1155, ERC1155Pausable)
    {
        super._update(from, to, ids, values);
    }
}

This ERC-1155 token smart contract was extracted from the Contract Wizard, setting no Base URI and activating Pausable feature. The constructor function was modified to include the minting of both a fungible and a non-fungible token.

With the contract compiled, next you will need to:

  1. Head to the Deploy & Run Transactions tab

  2. Change the environment to Injected Provider. This will use MetaMask's injected provider. Consequently, the contract will be deployed to whatever network MetaMask is connected to. MetaMask might show a pop-up outlining that Remix is trying to connect to your wallet

  3. Select the proper contract to deploy. In this example, it is the MyToken contract inside the ERC1155.sol file

  4. Enter the address of the initial owner and click on the Deploy button. Review the transaction information in MetaMask and confirm it

  5. After a few seconds, the transaction should get confirmed, and you should see your contract under Deployed Contracts

And that is it! You've deployed an ERC-1155 token contract using OpenZeppelin's contracts and libraries. Next, you can interact with your token contract via Remix.

This tutorial is for educational purposes only. As such, any contracts or code created in this tutorial should not be used in production.The information presented herein has been provided by third parties and is made available solely for general information purposes. Phron does not endorse any project listed and described on the Phron Doc Website (https://docs.Phron.ai/). Phron does not warrant the accuracy, completeness or usefulness of this information. Any reliance you place on such information is strictly at your own risk. Phron disclaims all liability and responsibility arising from any reliance placed on this information by you or by anyone who may be informed of any of its contents. All statements and/or opinions expressed in these materials are solely the responsibility of the person or entity providing those materials and do not necessarily represent the opinion of Phron. The information should not be construed as professional or financial advice of any kind. Advice from a suitably qualified professional should always be sought in relation to any particular matter or circumstance. The information herein may link to or integrate with other websites operated or content provided by third parties, and such other websites may link to this website. Phron has no control over any such other websites or their content and will have no liability arising out of or related to such websites or their content. The existence of any such link does not constitute an endorsement of such websites, the content of the websites, or the operators of the websites. These links are being provided to you only as a convenience and you release and hold Phron harmless from any and all liability arising from your use of this information or the information provided by any third-party website or service.

Last updated