在前一篇中介紹了 ERC721 的功能以及價值,但是了解了這些東西仍離真正的接觸 NFT 還有一段距離。因此這篇我想要講解如何 deploy 一個 ERC721 的 contract 到鏈上,並用自己的 metamask 錢包 mint 一個專屬於自己的 NFT。但是這那之前會先介紹一下 ERC721 的功能有哪些。
P.S. 雖然上一章有提及了 ERC20 的函式,但是有些功能如 mint()
、burn()
不包含在那些基本的函式中,通常是只有做 ICO 的人會使用到的函式,如果有興趣的可以看這個合約內容
下面幾個是與 ERC20 中相同的 function,基本上功能就與 ERC20 token 一模一樣,因此不再贅述。
function name() constant returns (string name);
function symbol() constant returns (string symbol);
function totalSupply() constant returns (uint256 totalSupply); // 總供給量
function balanceOf(address owner) constant returns (uint balance) // owner 的 token 數
ERC721 協議中的 function 總共有 10 個,event 共 3 個。
contract ERC721 is ERC165{ // 需要繼承 ERC165
function ownerOf(uint256 tokenId) external view returns (address owner);
function approve(address _to, uint256);
function takeOwnership(uint256 _tokenId);
// Function Overloading
function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes data) external payable;
function safeTransferFrom(address _from, address _to, uint256 _tokenId) external payable;
function transferFrom(address _from, address _to, uint tokenId) external payable;
function approve(address _approved, uint256 _tokenId) external payable;
function setApprovalForAll(address _operator, bool _approved) external;
function getApproved(uint256 _tokenId) external view returns(address);
function isApprovedForAll(address _owner, address _operator) external view returns (bool);
event Transfer(address _from, address _to, uint256 tokenId);
event Approval()
event ApprovalForAll()
}
mapping (uint256 => address) ownerOf;
// 輸入 tokenId=0 的 owner
ownerOf[0] = 0x5c6B0f7Bf3E7ce046039Bd8FABdfD3f9F5021678
_from
的 token 所有權轉移給 _to
。safetransferFrom()
限制了下面幾件事:
_from
和 _to
不能為 zero address。ownerOf(_tokenId) == _from
msg.sender
(call 這個 function 的地址)需為_from
或是經過 approved()
的地址或是此 token 被 setApprovalAll()
。_to
是一個合約地址,會 call 那個合約中的 onERC721Received()
。transferFrom()
將 token 轉到一個 zero address,會直接讓這個 token 變成一個遺失物,因此現在多建議使用 safetransferFrom()
而不用 transferFrom()
了。approve()
後的地址可以執行 safeTransferFrom()
來進行交易。msg.sender
需要是 NFT 的擁有者或是經過 approve()
的地址,且這個地址同一時間只會有一個,因此如果今天某個 approve()
後的地址呼叫了這個 function,但是他做了這件事approve(0,tokenId)
,此時 approve()
的地址就會被清除。Approval()
。_approved
== true
: 代表 operator 擁有交易權。_approved
== false
: 代表撤回 operator 的權力。ApprovalForAll()
。Transfer()
會在 token 交易的時候 emit 出來,可能會有三種情況:
_from
是 0 代表這筆交易是 mint token。_to
是 0 代表這筆交易是 burn token。_from
和 _to
都不是 0 代表是正常的交易。Mint (verb) : to produce a coin for the government (取自劍橋辭典)
在實作之前,我想再介紹一個概念 -- MINT。Mint 的中文為鑄造錢幣的意思(這邊不是指薄荷:)),而一種 ERC721 token 可能會使用兩種方式來鑄造 token。
以下的部分會只有合約的內容,並利用 remix 來做函式呼叫。
首先第一個步驟先打開 Openzepplin 的官網,進入 Contract,找到 Contract 中的 Docs,在左邊的欄位選擇 wizard,將會顯示下面的畫面。
這個 wizard 有點像一個模板,你可以選擇你想要的 token 種類,裡面需要什麼功能,wizard 就會自動的幫你放上去,並且 import Openzepplin 自己的合約。
FirstToken
、Symbol 輸入 FT
(也可以輸入你想要的名稱哈哈)。// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
contract FirstToken is ERC721, Ownable {
using Counters for Counters.Counter;
Counters.Counter private _tokenIdCounter;
constructor() ERC721("FirstToken", "FT") {}
function safeMint(address to) public onlyOwner {
uint256 tokenId = _tokenIdCounter.current();
_tokenIdCounter.increment();
_safeMint(to, tokenId);
}
}
Counter
: 他其實就是一個用來計算 tokenId
的 Library,可以見 Openzepplin 的合約內容。
_tokenIdCounter
是一個 structure,其中 attribute 是一個 uin256。ownerable
: 是一個 modifier,可以確認 msg.sender
是不是 該 NFT 的 owner
。_safeMint
: 將新的一枚 token mint 到 to
的帳戶中。接下來需要大家先安裝 chrome/edge/firefox/brave 或其他瀏覽器上的 Metamask,關於創立帳戶,這邊有更仔細的教學。
在安裝完小狐狸錢包後,需要測試網中的測試幣,連接這邊的水龍頭領取!(這邊使用的是 goerli 測試網)
進入後將你 metamask 的地址輸入,裡面的合約就會送 goerli ETH 給你了。(但上述的 faucet 需要登入 Alchemy 的帳號才可以拿到)
拿到後你可以在 metamask 中將你的網路改變成 goerli testnet,確認是否得到了 ETH。
隨後我們把剛剛的 wizard 中拿到的程式碼,複製到 remix(一種 IDE)上並貼上!我自己是在 workspaces 創立一個新的 blank 專案,並放入 Day5_First_NFT.sol 中。
並將 deploy(預設應該是由上數下來的第四個)中的 environment 設為 Injected Provider - Metamask,metamask 便會跳出來叫你登入(記得網路要選擇 goerli testnet)。
登入後,在 CONTRACT 選擇 FirstToken
(或你自己取的合約名稱),按下 deploy!此時就會跳出這個畫面:
按下後這張合約就成功的 deploy 在測試鏈上了。
接下來點入下方的 Deployed Contracts,展開後可以看見一堆 function,找到 safeMint,並在 address to
中輸入你自己的地址。再次的送出交易,成功後擬就成功的 mint 你的第一個 NFT 了!
可以再用下面的 function 來看看這枚 token 是否真的到了你的地址中。像是 ownerOf
中輸入 0(第一枚 mint 出來的編號是 0 XDD)。
Openzepplin 的合約真的是一個好東西,除了方便(你只需要 import 他們的合約就可以完成很多事情)以外安全性也很棒!我也觀察到其實很多 NFT 項目方也使用他們的合約來 deploy,所以是值得信任的!另外 NFT 也有一個大重點會在明天提到,請大家期待一下哈哈!
若有文章內有任何錯誤的地方歡迎指點與討論!非常感謝!
歡迎贊助窮困潦倒大學生
0xd8538ea74825080c0c80B9B175f57e91Ff885Cb4