-
Notifications
You must be signed in to change notification settings - Fork 155
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #787 from anistark/docs/tutorial-erc721
added ERC721 tutorial
- Loading branch information
Showing
7 changed files
with
170 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,170 @@ | ||
--- | ||
title: ERC721 Example | ||
keywords: | ||
- IOTA | ||
- Smart Contracts | ||
- EVM | ||
- Solidity | ||
- ERC721 | ||
- eip-721 | ||
- token creation | ||
- mint tokens | ||
description: Create and deploy a Solidity smart contract to mint NFTs using the ERC721 standard. | ||
image: /img/evm/ozw-721.png | ||
--- | ||
# ERC721 Example | ||
|
||
:::info note | ||
|
||
Please keep in mind that this is an EVM only NFT. It's not tied to L1 native assets. Also, these are different from L1 NFTs. | ||
|
||
::: | ||
|
||
Non-fungible tokens or NFTs are a type of token that can represent any unique object including a real world asset on a decentralised network. | ||
|
||
|
||
## Prerequisites | ||
|
||
- What is a token? | ||
- What is a blockchain? | ||
- What are ERCs? | ||
- What is an NFT? | ||
- What is a smart contract? | ||
- How to get started with Solidity? | ||
|
||
|
||
## About ERC721 | ||
|
||
NFTs are most commonly represented with ([ERC721 standard](https://eips.ethereum.org/EIPS/eip-721)). You can use the openzepplin lib [`@openzeppelin/contracts/token/ERC721/ERC721.sol`](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/ERC721.sol) to simplify. | ||
|
||
You can also use the ([OpenZepplin Contracts Wizard](https://wizard.openzeppelin.com/#erc721)) to generate and customize your smart contract. | ||
|
||
The following is an example NFT Smart Contract called "HuskyArt". | ||
|
||
```solidity | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.2; | ||
import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; | ||
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol"; | ||
import "@openzeppelin/contracts/access/Ownable.sol"; | ||
import "@openzeppelin/contracts/utils/Counters.sol"; | ||
contract HuskyArt is ERC721, ERC721URIStorage, Ownable { | ||
using Counters for Counters.Counter; | ||
Counters.Counter private _tokenIdCounter; | ||
constructor() ERC721("HuskyArt", "HSA") {} | ||
function _baseURI() internal pure override returns (string memory) { | ||
return "https://example.com/nft/"; | ||
} | ||
function safeMint(address to, string memory uri) public onlyOwner { | ||
uint256 tokenId = _tokenIdCounter.current(); | ||
_tokenIdCounter.increment(); | ||
_safeMint(to, tokenId); | ||
_setTokenURI(tokenId, uri); | ||
} | ||
// The following functions are overrides required by Solidity. | ||
function _burn(uint256 tokenId) internal override(ERC721, ERC721URIStorage) { | ||
super._burn(tokenId); | ||
} | ||
function tokenURI(uint256 tokenId) | ||
public | ||
view | ||
override(ERC721, ERC721URIStorage) | ||
returns (string memory) | ||
{ | ||
return super.tokenURI(tokenId); | ||
} | ||
} | ||
``` | ||
|
||
As you can see above, the contract uses standard methods for the most part. You should pay attention to the following: | ||
|
||
- `pragma solidity ^0.8.2;` This line means that the contract uses solidity compiler version 0.8.2 or above. | ||
- `constructor() ERC721("HuskyArt", "HSA") {}` This defines the token name and symbol. You can name it whatever you want. We recommend that you use the same name for the token and the contract. | ||
- `import "@openzeppelin/contracts/utils/Counters.sol";` This lib is used to create auto-incremental ids for the tokens. | ||
- `return "https://example.com/nft/";` You should define the base URI of your NFTs will be. That means the URL you provide here will be used for all your tokens going forward. Since this contract uses auto-incremental token ids, your token URI will look something like `https://example.com/nft/0`, `https://example.com/nft/1`, `https://example.com/nft/2`, and so on. | ||
- `function safeMint(address to, string memory uri) public onlyOwner {` is the safeMint function. This function will require that you manually input a token's `to` address and a `uri` every time you want to mint one. This should work for regular use-cases. | ||
- `// SPDX-License-Identifier: MIT` This line specifies the license type. You do not need to worry about this for this example. If you want to keep it unlicensed, you replace it with `// SPDX-License-Identifier: Unlicensed`. | ||
|
||
![Open Zepplin Wizard](/img/evm/ozw-721.png) | ||
|
||
You can customize your contract further depending on how you would like it to behave. You should consider the following topics and questions: | ||
|
||
1. **Ownership** — Who owns it? How is it stored? | ||
2. **Creation** — Method or Type of Creation. | ||
3. **Transfer & Allowance** — How will tokens be transferred? How will they be available to other addresses and accounts? | ||
4. **Burn** — Do you want to destroy it? If yes, how? | ||
|
||
You can click on **Copy to Clipboard** and paste it in the IDE of your choice, download it, or click on open in Remix directly. This example uses Remix. | ||
|
||
|
||
## Compile | ||
|
||
Compile your Smart Contract to generate the ABI and Bytecode. | ||
|
||
![Remix Compile](/img/evm/remix-721.png) | ||
|
||
You can check `Auto Compile` so that you do not have to compile manually with every change you make. | ||
|
||
After you have successfully compiled your smart contract, you can proceed to [deploy it](#deploy). | ||
|
||
|
||
## Deploy | ||
|
||
### Connect your IDE to the network where you want to deploy the smart contract. | ||
|
||
This example uses the [Remix IDE](https://remix.ethereum.org/) with [Metamask](https://metamask.io/) to handle this task. If you are using hardhat or truffle, you should customize the config file accordingly. | ||
|
||
|
||
### Connect to the ISCP Testnet | ||
|
||
You can find instructions on this in the [devnet endpoints section](https://wiki.iota.org/smart-contracts/guide/chains_and_nodes/testnet#endpoints)).``` | ||
|
||
### Change the Environment to Injected Web3 | ||
|
||
After you have completed the prior steps, please select the `Injected Web3` network as pictured below. | ||
|
||
![Remix VM Select](/img/evm/remix-vm-injected.png) | ||
|
||
Wait for the IDE to sync. If it does not, please refresh and try again. | ||
|
||
## Select Your Smart Contract From the Dropdown | ||
|
||
### Select Your New Smart Contract | ||
|
||
Once you have [changed the environment to injected web3](#change-the-environment-to-injected-web3), you can proceed to select your Smart Contract from the dropdown. Ideally, you will see only one option here. However, since your contract imports quite a few libs, those may show up by default. | ||
|
||
![Remix Deploy](/img/evm/remix-721-deploy.png) | ||
|
||
### Deploy Your Contract | ||
|
||
Click on `Deploy`. This should open Metamask and ask you to sign the transaction. Please do so and wait for confirmation. | ||
|
||
![Remix Deployed](/img/evm/remix-deployed.png) | ||
|
||
If you see something like this, your contract is now deployed. You can also verify this on the explorer or explore more on Metamask. | ||
|
||
![Remix Deployed](/img/evm/remix-metamask-detail.png) | ||
|
||
:::note | ||
The node which was used in this example has `0` gas fees. However, depending on which node you choose to deploy to, there may be some gas fees. | ||
::: | ||
|
||
|
||
## Possible Next Steps | ||
|
||
The above smart contract is generated by OpenZepplin Wizard and is good enough to be used in production environments. However, you may want more conditions or actions added to it. For example, you could add royalty for every transfer done after minting. | ||
|
||
|
||
## Further Reading | ||
|
||
- [OpenZepplin 721 Standard](https://docs.openzeppelin.com/contracts/2.x/api/token/erc721) | ||
|
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.