# NFT Collection Overview and Minting in Rust
In this tutorial we will mint an NFT collection in Rust according to the IRC-27 standard on the Shimmer testnet. We will also get a thorough understanding of the concept and the technical implementation of an NFT collection.
## What is an NFT collection?
Fundamentally, an NFT collection is a set of NFTs that have one similar theme, but in most cases have different traits and attributes which give each NFT its own unique character. Collections usually consist of an initial fixed size which is deemed to not change in order to prevent the dilution of value of each NFT. As we will see later on there is a special mechanism defined in IRC-27 which ensures that no NFTs are minted after the initial minting.
NFT collections are not a new concept unique to IOTA. They exist in other ecosystems by utilizing smart contracts which verify that an NFT does indeed belong to a collection. On Ethereum for example this can be achieved by deploying an ERC-721 smart contract. The EVM on IOTA Smart Contracts (ISC) also supports [ERC-721 smart contracts](https://wiki.iota.org/shimmer/smart-contracts/guide/evm/examples/ERC721).
With the release of the [Stardust](https://wiki.iota.org/shimmer/introduction/explanations/what_is_stardust) protocol upgrade, NFT collections can be natively implemented on Layer 1 without the need for any smart contracts. This has been standardised by the community in IRC-27.
### IRC-27
Since we do not utilize smart contracts which ensure that a certain NFT belongs to a collection, IRC-27 makes use of the [Issuer Output Feature](https://wiki.iota.org/shimmer/introduction/explanations/what_is_stardust/output_features#issuer) which has been introduced with Stardust. It allows to prove that an NFT has been minted by a certain issuer to prevent "counterfeit" NFTs impersonating real NFTs from the collection issuer.

#### Collection NFT
Before minting all the NFTs of a collection, we mint the _Collection NFT_. However, the Collection NFT itself will not be a part of the actual collection, but will represent the central identity of our NFT collection.
Since L1 NFTs on Stardust can own and issue other assets (like other NFTs), our Collection NFT will be the issuer of all NFTs within the collection. The aforementioned Issuer Output Feature ensures that the issuer of each NFT which is part of the collection can be traced back to the Collection NFT.
As can be seen in the diagram above, the `nftID` of the Collection NFT is specified as the _immutable issuer_ of all minted NFTs.
To prevent subsequent minting, the Collection NFT can be burned after all NFTs which should make up the collection have been minted.
#### Metadata
Each NFT should have metadata which is immutable and defined before minting. To guarantee interoperability the metadata is specified in [JSON](https://www.json.org/json-en.html). IRC-27 clearly defines the attributes for each NFT. Let's have a look at this sample NFT metadata:
```json
{
"standard": "IRC27",
"version": "v1.1",
"type": "image/gif",
"uri": "https://my-awesome-nft-project.com/item-4.gif",
"name": "#4 My Awesome NFT",
"issuerName": "Me",
"royalties": {
"rms1q5948....": 0.05
},
"collectionName": "My Awesome NFT Collection",
"attributes": [
{
"trait_type": "awesomeness",
"value": 60
}
]
}
```
The first five attributes are mandatory:
- `standard` and `version` specify how the metadata should be interpreted. They should not be modified.
- Common `types` are (choose appropriate):
- Image files: `image/jpeg`, `image/png`, `image/gif`, etc.
- Video files: `video/x-msvideo` (avi), `video/mp4`, `video/mpeg`, etc.
- Audio files: `audio/mpeg`, `audio/wav`, etc.
- 3D Assets: `model/obj`, `model/u3d`, etc.
- Documents: `application/pdf`, `text/plain`, etc.
- The `uri` is the link pointing to the asset of each NFT. Adjust it accordingly. Assets stored in _IPFS_ can be preceded with `ipfs://` followed by the asset's [hash](https://docs.ipfs.tech/concepts/what-is-ipfs/#content-addressing).
- The `name` can be chosen freely. Usually it contains the NFT number within the collection.
The remaining attributes are optional. For more detailed information consult IRC-27.
## Minting in Rust
Considering that a collection may consist of hundreds or thousands NFTs we opted for the more performant `iota.rs` Rust library in comparison to the `iota.js` TypeScript library.
### Prerequisites
- Rust needs to be installed. The easiest way to achieve this is by utilizing the `rustup` tool. Follow the tutorial [here](https://www.rust-lang.org/tools/install).
- [Clone](https://docs.github.com/en/repositories/creating-and-managing-repositories/cloning-a-repository) the Repo containing the [tutorial code](https://github.com/iota-community/shimmer-nft-collection-rust).
### Minting
On Mac/Linux open the Terminal, on Windows the [Powershell](https://learn.microsoft.com/en-us/powershell/scripting/windows-powershell/starting-windows-powershell?view=powershell-7.3) and with the `cd` [command](https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/cd) navigate to the root folder of the cloned repo.
0. Create a copy of the sample `.env.example` file:
```bash
cp .env.example .env
```
Change the values in the newly created `.env` file.
- The file contains preset values for the mnemonic which will be the key to the generated account which will hold the NFTs. Replace the mnemonic with a fresh 24 word BIP39 mnemonic to avoid interfering with others who use the preset one.
- Make sure to choose a secure [Stronghold](https://wiki.iota.org/shimmer/stronghold.rs/welcome) password.
1. Start off by creating a new `account`:
```bash
cargo run --bin create-account --release
```
2. Generate an address which belongs to the account you just created:
```bash
cargo run --bin get-address --release
```
The command should return an address starting with `rms`.
Now you need to send Shimmer testnet tokens to the address. You can use the [Shimmer Faucet](https://faucet.testnet.shimmer.network/). The tokens are necessary to pay for the [storage deposit](https://wiki.iota.org/shimmer/introduction/explanations/what_is_stardust/storage_deposit). Additionally, you can request tokens multiple times should you receive an error message later on that you do not have sufficient funds sitting on your address.
3. Create the Collection NFT by running:
```bash
cargo run --bin create-collection-nft --release
```
The Collection NFT will be minted to the account you initially created. You can view the accounts balance by running:
```bash
cargo run --example get_balance --release
````
4. Mint NFTs
1. Adjust the `nft_collection_size` in `src/create-nfts/main.rs`. For testing we would recommend smaller sizes since the minting takes less time due to a reduction in [PoW](https://wiki.iota.org/shimmer/introduction/explanations/what_is_stardust/dynamic_pow) calculations.
2. Copy the `nftId` from the Collection NFT (contained in output of above balance command) and replace the preset `issuer_nft_id` in `src/create-nfts/main.rs` with it.
3. Replace `immutable_metadata` with the metadata you put together (see previous section). If your artwork filename (contained in the `uri`) increments with each NFT, you can replace the variable part with `{index}`. For example if you had artworks named `shimmer-#1.png`, `shimmer-#2.png` and so on, you would specify the filename as `shimmer-#{index}.png`.
Finally mint the NFT collection by running:
```bash
cargo run --bin create-nfts --release
```
Depending on the size of your collection this command may take some time to complete.
Congratulations, you have just minted your first NFT collection on Shimmer. You can see the NFTs in your account by running:
```bash
cargo run --example get_balance --release
````
You can also copy the `nftId` into the [Shimmer Testnet Explorer](https://explorer.shimmer.network/testnet) to see more details regarding your NFT.
### Optional steps
#### Distribute NFTs
If you want to distribute the NFTs directly afterwards, you can copy a CSV file containing all the addresses into the root folder of the repo.
5. Send NFTs to addresses in the CSV file by running the following command. Make sure to adjust the `filename.csv`.
```bash
cargo run --bin send-nfts-to-csv --release < filename.csv
```
#### Lock Collection NFT
In case you want to prevent further minting of NFTs within your collection, you can lock the Collection NFT forever by sending it to the zero address.
Copy the `nftId` from the Collection NFT (contained in output of initial balance command) and replace the preset `nft_id` in `src/lock-collection-nft/main.rs` with it.
Afterwards execute it by running:
```bash
cargo run --bin lock-collection-nft --release
```