# Create Your ERC721 Contract

<figure><img src="https://2372007595-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F0Tecsoe4KNURIiIXeVdO%2Fuploads%2FjcML3wjeIt7UNnk44u9N%2FCreate%20Your%20ERC721%20Contract.png?alt=media&#x26;token=3bfa2a40-9cf7-4f17-8918-6c0d82ac17f7" alt=""><figcaption></figcaption></figure>

### Install Dependencies&#x20;

We will build your ERC721 contract based on the Openzeppelin contracts. Let's install Openzeppelin contracts for our foundry project:&#x20;

```bash
forge install openzeppelin/openzeppelin-contracts 
```

Foundry installs all dependencies as git submodules under the directory of "lib". And to make it easier to import the dependencies, let's create a `remappings.txt` file with the following contents:&#x20;

```
openzeppelin-contracts=lib/openzeppelin-contracts
```

{% hint style="info" %}
The `remapping.txt` file should be put in the project root directory (i.e., the directory that contains the`foundry.toml` file. )
{% endhint %}

With the `remappings.txt` file above, we can import the ERC721 contract from Openzeppelin by the following `import statement` :&#x20;

```solidity
import "openzeppelin-contracts/contracts/token/ERC721/ERC721.sol";
```

### The ERC721 Contract&#x20;

Create a new file named "MyNFT.sol" under the directory of "src".  The content in the file is as follows:&#x20;

```solidity
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;

import "openzeppelin-contracts/contracts/token/ERC721/ERC721.sol";
import "openzeppelin-contracts/contracts/access/Ownable.sol";

contract MyNFT is ERC721, Ownable{

    string private _URIBase;

    constructor(string memory name_, string memory symbol_) ERC721(name_, symbol_) {
        _transferOwnership(msg.sender);
    }

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

    function setBaseURI(string memory baseURI_) public onlyOwner {
        _URIBase = baseURI_;
    }

    function _baseURI() internal view override returns (string memory) {
        return _URIBase;
    }
}
```

{% hint style="info" %}
In this toy ERC721 contract, we have added some customized logics:

* The deployer of the contract will be the owner of the contract.&#x20;
* Only the owner can mint a new NFT token. However, he can mint the token to another address.&#x20;
* Only the owner can change the base URI of the Token URI.&#x20;
  {% endhint %}

### Deploy Your ERC721 Contract&#x20;

```bash
FOUNDRY_PROFILE=kcc_testnet \
    forge create \
    --constructor-args "my-nft" "M" 
    --private-key=XXXXXXXXXXXXXXXXX  \
    --legacy  src/MyNFT.sol:MyNFT
```

{% hint style="info" %}
We use `--constructor-args` to specify the arguments for our constructor.
{% endhint %}

If everything goes well, forge will print out the address of the deployed contract and the transaction hash for the deployment.&#x20;

### Mint An NFT&#x20;

We can use `cast` from `foundry`  to interact with our ERC721 contract. Let's mint an `NFT` with `cast`:&#x20;

```bash
FOUNDRY_PROFILE=kcc_testnet cast send  \
    --private-key=XXXXXXXXXXXX  --legacy \
    0xd382De234f8d3f1DB54C856498a9DbC84c \
    'mint(address,uint256)'  \
    0x6Dfc34a4a2FC03Ba5d5ff95566781bD2b39702fc 1337
```

{% hint style="info" %}

* You should replace `0xd382De234f8d3f1DB54C856498a9DbC84c` with the address of your ERC721 contract.&#x20;
* And `0x6Dfc34a4a2FC03Ba5d5ff95566781bD2b39702fc` is the address that receives the newly minted NFT.&#x20;
* Finally, `1337` is the id of the newly minted NFT.&#x20;
  {% endhint %}

We can also verify the owner of this newly minted NFT by using `cast` again:&#x20;

```
FOUNDRY_PROFILE=kcc_testnet \
        cast call  0xd382De234f8d3f1DB54C856498a9DbC84c \
        'ownerOf(uint256)(address)' 1337
```
