---
tags: it 鐵人賽 30 天, Web 3, ethereum
---
# 從以太坊白皮書理解 web 3 概念 - Day23
## NFT School Day 1 - 初始化環境 - 建立與 Greeting Contract 互動的 Dapp
前面講述完基本的 Token 概念
在接下來的 8 天將會透過 [NFT school](https://nftschool.dev/) 的內容
逐步介紹 NFT 並且在測試鏈建構一個 NFT
## 什麼是 NFT
NFT 代表的是 Non-Fungible Token 也就是所謂非同質化 Token
從上面的解釋,可以知道 NFT 是一種 Token 也就是一樣是符合某些標準的 Smart Contract
這種 Token 具有非同質化特性
同質化指的是兩個不同的東西具有取代性,比如說 Alice 的 5 元銅板 與 Bob 的 5 元銅板
彼此之間互換也不會造成任何不同
非同質性則是代表每個不同的東西都無法取代具有唯一性,比如說畢卡索的任何一個畫作
每一個畫作因為其特殊的藝術性而有所不同是無法彼此取代
所以非同質 Token 就是一種每個 Token 都具有唯一性無法取代的 token
而這種唯一性不只是因為使用唯一識別代號
並且是因為 NFT 會對應到一個在現實世界的物件內容
其內容因為據為紀念性而有不同
可以想像 NFT 就像是某個現實物件的對應到 Blockchain 上的所有權
## NFT 生命周期

NFT 透過 Mint(鑄造) 產生出來把數位資產放到區塊鏈上
然後透過一些販售 NFT 的平台比如 OpenSea 等等
當有人想要該 NFT 原本持有人可以透過 Transfer 轉移 NFT 所有權
NFT 持有人也可以透過 Burn 來銷毀 NFT
## 基礎設定
為了開發 NFT 以下需要做一些基礎設定
### 設定 MetaMask
1. 透過 [https://metamask.io/download.html]( https://metamask.io/download.html) 下載安裝 MetaMask for Chrome extension
2. 設定 MetaMask 錢包的帳戶 與記憶詞

3. 選擇 Sepolia 測試鏈
* 先選擇顯示測試網路(預設不顯示)

* 切換為 Sepolia 測試鏈

4. 從測試鏈 faucet 拿取測試 ether
* 先按下畫面下的 Buy

* 選擇從 test fault 取得 ETHER

* 填入 address 接收 ETHER

### 初始化資料夾
```shell=
mkdir hello_eth
cd hello_eth
```
下載 https://cdn.ethers.io/lib/ethers-5.1.esm.min.js 到 hello_eth 資料夾
### 安裝 HTTP server
```shell=
yarn global add http-server
```
### 撰寫與 Contract 互動的 Javascript 內容
```javascript=
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hello Ether</title>
<script type="module">
import { ethers } from "./ethers-5.1.esm.min.js";
// Your code here...
const contractReturn = document.querySelector('.output');
const GREETER_ADDRESS = '0xeF802A416c1E5fC3F198620E685b958D6d0EA2c9'
const GREETER_ABI = `[{"inputs":[{"internalType":"string","name":"_greeting","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"greet","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_greeting","type":"string"}],"name":"setGreeting","outputs":[],"stateMutability":"nonpayable","type":"function"}]`
async function getGreeting() {
// Wrap the window.ethereum object injected by MetaMask with the ethers API
const provider = new ethers.providers.Web3Provider(window.ethereum);
// Connect to the greeter contract.
const greeterContract = new ethers.Contract(GREETER_ADDRESS, GREETER_ABI, provider);
// Call the greet() smart contract function.
const greeting = await greeterContract.greet();
console.log(greeting)
// Write the greeting result to the DOM.
contractReturn.textContent = `hello ` + greeting;
}
getGreeting();
</script>
</head>
<body>
<div class="output"></div>
</body>
</html>
```
這個網頁是與位址在 0xeF802A416c1E5fC3F198620E685b958D6d0EA2c9 的 Greeter Contract 做互動
透過 abi 呼叫 Greeter Contract 的 greet function
Geeter Contract 內容如下
```solidity=
//SPDX-License-Identifier: Unlicense
pragma solidity ^0.7.0;
import "hardhat/console.sol";
contract Greeter {
string greeting;
constructor(string memory _greeting) {
console.log("Deploying a Greeter with greeting:", _greeting);
greeting = _greeting;
}
function greet() public view returns (string memory) {
return greeting;
}
function setGreeting(string memory _greeting) public {
console.log("Changing greeting from '%s' to '%s'", greeting, _greeting);
greeting = _greeting;
}
}
```
可以看出 greet 回復內的內容與存在 greeting 的值相關
這邊因為我已經把 greeting 內容設定成 "GSON"
所以會傳的結果也是 GSON
### 驗證結果
在 hello_eth 執行
```shell=
http-server .
```

然後打開瀏覽器

到這裡環境設定基本上就可以確認 可以透過 ethers library 與測試鏈做互動
## 參考文獻
[https://docs.ethers.io/v5/getting-started/#getting-started--importing--web-browser](https://docs.ethers.io/v5/getting-started/#getting-started--importing--web-browser)
[https://nftschool.dev/tutorial/first-steps/#building-our-app](https://nftschool.dev/tutorial/first-steps/#building-our-app)
[https://ropsten.etherscan.io/address/0xE0282e76237B8eB19A5D08e1741b8b3e2691Dadd#code](https://ropsten.etherscan.io/address/0xE0282e76237B8eB19A5D08e1741b8b3e2691Dadd#code)
[https://xrpl.org/non-fungible-tokens.html](https://xrpl.org/non-fungible-tokens.html)