## IPFS介紹
#### 我們這次要使用IPFS(Pinata)來存放我們的NFT圖片。
有關IPFS以及Pinata介紹,請看這篇文章 [IPFS介紹](https://hackmd.io/7vj9f0HiQXGfo_j1_u0KfA?view)
## 上傳圖片至Pinata
我們使用Pinata當作我們儲存圖片的IPFS系統。
[Pinata上傳圖片頁面](https://app.pinata.cloud/pinmanager)

首先我們點選右上角的 "Add Files" 按鈕,然後點選 "File",會有上傳視窗讓你選擇圖片。

這邊可以隨意上傳隨便一張圖片,GIF檔也可以。

上傳好後,我們可以看到有出現我們剛剛上傳的檔案以及對應的CID,這個CID就是你圖片的類似代號的東西,我們待會在Mint NFT的時候會用到。

## Publisher + Display
這次主要會使用到Publisher以及Display兩個Sui Framwork內的module。
#### Publisher
作為代表發布者權限的一種方式。
該物件本身並沒有任何特定的用法,有兩個主要驗證的功能:```package::from_module<T>```以及```package::from_package<T>```
檢查類型T是否屬於為其Publisher創建物件的package或module。
要設置Publisher,需要一次性見證(OTW) - 通過這種方式,我們確保Publisher僅初始化一次。
#### Object Display
擁有Publisher對象的創建者或構建者可以使用```sui::display```來定義其物件的顯示屬性。
Sui Object Display 是一個模板顯示標準,允許在鏈上顯示配置。它能夠把鏈下數據替換到模板中。
可以設置哪些字段沒有限制,所有對象屬性都可以通過語法訪問{property}並作為模板字符串的一部分插入。
目前定義的模板內容如下:
```javascript
{
"name": "{name}", //顯示名稱
"link": "https://sui-heroes.io/hero/{id}", //可以放入連結到自己的商品網址
"image_url": "ipfs://{img_url}", //使用ipfs(推薦)或是一般Https圖片網址
"description": "A true Hero of the Sui ecosystem!", //敘述
"project_url": "https://sui-heroes.io", //放入連結到自己的網站
"creator": "Unknown Sui Fan" //創建人名稱
}
```
## NFT智能合約
```rust
module nft_demo::my_hero {
use sui::tx_context::{Self, TxContext};
use std::string::{Self, String};
use sui::transfer;
use sui::object::{Self, UID};
use sui::package;
use sui::display;
struct Hero has key, store {
id: UID,
name: String,
img_url: String,
description: String,
creator: String
}
/// One-Time-Witness for the module.
struct MY_HERO has drop {}
fun init(otw: MY_HERO, ctx: &mut TxContext) {
let keys = vector[
string::utf8(b"name"),
string::utf8(b"link"),
string::utf8(b"image_url"),
string::utf8(b"description"),
string::utf8(b"project_url"),
string::utf8(b"creator"),
];
let values = vector[
// For `name` we can use the `Hero.name` property
string::utf8(b"{name}"),
// For `link` we can build a URL using an `id` property
string::utf8(b"https://sui-heroes.io/hero/{id}"),
// For `image_url` we use an ipfs :// + `img_url` or https:// + `img_url`.
string::utf8(b"{img_url}"),
// Description is static for all `Hero` objects.
string::utf8(b"{description}"),
// Project URL is usually static
string::utf8(b"https://sui-heroes.io"),
// Creator field can be any
string::utf8(b"{creator}")
];
// Claim the `Publisher` for the package!
let publisher = package::claim(otw, ctx);
// Get a new `Display` object for the `Hero` type.
let display = display::new_with_fields<Hero>(
&publisher, keys, values, ctx
);
// Commit first version of `Display` to apply changes.
display::update_version(&mut display);
transfer::public_transfer(publisher, tx_context::sender(ctx));
transfer::public_transfer(display, tx_context::sender(ctx));
}
/// Anyone can mint their `Hero`!
public entry fun mint(
name: String,
img_url: String,
description: String,
creator: String,
ctx: &mut TxContext
) {
let id = object::new(ctx);
let hero = Hero {
id,
name,
img_url,
description,
creator
};
transfer::public_transfer(hero, tx_context::sender(ctx));
}
/// Permanently delete `nft`
public entry fun burn(nft: Hero) {
let Hero {
id,
name: _ ,
img_url: _ ,
description: _ ,
creator:_
} = nft;
object::delete(id);
}
}
```
### 部署智能合約
把智能合約部署上鏈後,我們可以使用 [Sui Explorer](https://suiexplorer.com/?network=testnet) 來使用我們剛剛開發的mint功能,來mint一個NFT給自己
### Mint NFT
先來查看要傳入哪些參數

第一個參數傳入NFT名稱
第二個參數傳入ipfs://{CID}

第三個參數傳入NFT敘述
第四個參數傳入建造者名稱


在我們的錢包內,點選Assets,也可看到我們剛剛mint出來的NFT

### Burn NFT
傳入需要銷毀的NFT Object ID

會發現Sui Explorer以及錢包都找不到該NFT了

