--- tags: it 鐵人賽 30 天, Web 3, ethereum --- # 從以太坊白皮書理解 web 3 概念 - Day24 ## NFT School Day 2 - 建立鑄造 NFT 的系統 - 透過 IPFS 與 Smart Contract 今天會透過 [minting system](https://nftschool.dev/tutorial/minting-service/) 學習透過 IPFS 與 Smart Contract 實作一個鑄造 NFT 的系統 所謂的鑄造就是建立一個 NFT,除了需要透過 Smart Contract 設定唯一識別代號並且需要設定一個該 token 所對應的實體物件 URI 。 為了方便實作這邊把實際物件設定為數位圖片,並且把數位圖片放到 ipfs 之上產生 hash 做識別號 把這個識別號設定為 NFT 的 URI ## 什麼是 IPFS?為何使用 IPFS? IPFS 是一種分散式存儲系統技術,對每個存入的檔案內容產生唯一識別代號,特別的是這個識別帶會是根據檔案內容所產生出來的。 所以可以避免檔案被更換而 NFT 持有者卻不知道 這邊範例採用 [nft.storage](https://nft.storage/) 這個專門放 NFT 數位資產的一個存儲服務是建構在 IPFS 之上的服務 ## 建構 IPFS 與 SMART Contract 這邊會採用 [scaffold-eth](https://github.com/scaffold-eth/scaffold-eth) 這個 Dapp 專案當作基底來建構 minting service 透過以下指令 clone 專案 ```shell= git clone https://github.com/ipfs-shipyard/nft-school-examples cd nft-school-examples/end-to-end ``` 安裝所需套件 ```shell= yarn install ``` 使用以下指定在 local 模擬 ```shell= yarn chain ``` 這個指令執行之後為顯示以下這些 account 資訊 ![](https://i.imgur.com/fvjCi7w.png) 這時候打開另一個 terminal 使用以下指令發佈 NFTMinter Contract 到鏈上 ```shell= yarn deploy ``` 然後就會看到以下畫面 ![](https://i.imgur.com/ks4kW0Q.png) 接著可以執行以下指令來執行 Dapp ```shell= yarn start ``` 透過執行 mint 動作 ![](https://i.imgur.com/VRAdJnI.png) 讀取 mint 完的 id ![](https://i.imgur.com/6zx5Ir1.png) ## minting 是如何運作的? 這邊是透過 NFTMinter Smart Contract 來建立 NFT Token NFTMinter Contract 如下 ```solidity= //SPDX-License-Identifier: MIT pragma solidity ^0.7.0; import "hardhat/console.sol"; import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; import "@openzeppelin/contracts/utils/Counters.sol"; contract NFTMinter is ERC721 { using Counters for Counters.Counter; Counters.Counter private _tokenIds; constructor(string memory tokenName, string memory symbol) ERC721(tokenName, symbol) { _setBaseURI("ipfs://"); } function mintToken(address owner, string memory metadataURI) public returns (uint256) { _tokenIds.increment(); uint256 id = _tokenIds.current(); _safeMint(owner, id); _setTokenURI(id, metadataURI); return id; } } ``` 可以注意到這邊只需要紀錄 nft.storage 所產生 uri 到對應的 token id 所以每次鑄造都會產生一個唯一識別代號 tokenId 並且把 nft.storage 所產生的 uri 儲存下來 ### 1. 把圖片上傳 nft.storage 語法如下: ```javascript= const client = new NFTStorage({ token: NFT_STORAGE_KEY }); const metadata = await client.store({ name, description, image, }); ``` ### 2. 呼叫 mintToken 功能 ```javascript= // our smart contract already prefixes URIs with "ipfs://", so we remove it before calling the `mintToken` function const metadataURI = metadata.url.href.replace(/^ipfs:\/\//, ""); // scaffold-eth's Transactor helper gives us a nice UI popup when a transaction is sent const transactor = Transactor(provider, gasPrice); const tx = await transactor(contract.mintToken(ownerAddress, metadataURI)); setStatus("Blockchain transaction sent, waiting confirmation..."); // Wait for the transaction to be confirmed, then get the token ID out of the emitted Transfer event. const receipt = await tx.wait(); let tokenId = null; for (const event of receipt.events) { if (event.event !== 'Transfer') { continue } tokenId = event.args.tokenId.toString(); break; } ``` ## 結語 這個 Dapp 實踐了鑄造 NFTToken 並且把內容讀取出來