智能合約教學(8) NFT合約

0 9
Avatar for vcckvv
Written by
1 year ago

依照預告,這次來講解怎麼寫NFT合約

首先一樣先來操作一下網站,獲得測試鏈的NFT:https://vcckvv.github.io/SmartContract/NFT/

使用到的合約位址和程式碼:

https://mumbai.polygonscan.com/address/0x8abb77ff22f8966729603bd49c5c049c4294efd5#code

這次的目標是要鑄造NFT並在OpenSea上顯示出來,因為OpenSea不支援goerli測試鏈,但是支援的rinkeby測試鏈之前有傳出不再升級、即將中止的消息(https://blog.ethereum.org/2022/06/21/testnet-deprecation/ ),所以這次是換到OpenSea另一個有支援的polygon Mumbai測試鏈

因為Mumbai測試鏈不是MetaMask內建的鏈,所以一般來說要在MetaMask中先輸入測試鏈的資料才能使用,不過這次我把新增Mumbai測試鏈的功能加到了網站之中,只要打開那個網站,MetaMask就會自動跳出要新增Mumbai測試鏈的視窗,接著也會自動要求連上Mumbai測試鏈

這邊應該沒多少人有用過Mumbai測試鏈,所以要先點網頁中的水龍頭連結https://mumbaifaucet.com/ 去取得測試鏈的原生代幣

MetaMask顯示收到MATIC幣後就可以來鑄造NFT,這個網頁有提供4種鑄造方式,前3種是同樣的兔子圖片,最後一種則是之前TEST代幣的圖標,隨便想要哪一種都可以,點選按鈕後簽署交易等待上鏈後就可以取得NFT了

接著到測試版的OpenSea上去看剛才取得的NFT:https://testnets.opensea.io/account ,如果太快打開可能OpenSea的系統還在處理所以看不到圖片,大概等交易上鏈一分多鐘後就能看到圖片了

------------------------------------------

接下來就來講解怎麼撰寫NFT合約,和之前撰寫ERC20代幣一樣,NFT合約實際上是符合另一個ERC721標準,只要合約中有某些特定的函數可以呼叫,那麼就會被視為NFT合約

這次一樣使用OpenZeppelin寫好的ERC721範例,來源為:

https://github.com/OpenZeppelin/openzeppelin-contracts/tree/master/contracts/token/ERC721

合約程式碼為:

https://github.com/vcckvv/SmartContract/blob/gh-pages/NFT/NFT.sol

------------------------------------------

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.14;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

contract NFT is ERC721, ERC721Enumerable, Ownable {
    
	string[] uriArr;
 
	constructor() ERC721("NFT Token", "NFT") {
		
	}
	
	function mint(string memory uri) public {
		require(bytes(uri).length > 0);

		_safeMint(msg.sender, uriArr.length);
		uriArr.push(uri);
	}

	function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
		require(tokenId < uriArr.length);

		return uriArr[tokenId];
	}

	function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal override(ERC721, ERC721Enumerable) {
		super._beforeTokenTransfer(from, to, tokenId);
	}

	function supportsInterface(bytes4 interfaceId) public view override(ERC721, ERC721Enumerable) returns (bool) {
		return super.supportsInterface(interfaceId);
	}
}

------------------------------------------

上面的程式碼原本有註解URI的範例輸入,不過因為之後會講到所以這裡先刪掉

------------------------------------------

解說:

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

這次並沒有把OpenZeppelin的檔案從中取出放到remix上,而是使用import的形式,remix可以用這種方式,直接從github網站中讀取出需要的程式碼

不過要注意etherscan和polygonscan的Verify and Publish並不支援這種import的形式,因此我又另外弄了一個程式碼把引用到的內容都丟進來:

https://github.com/vcckvv/SmartContract/blob/gh-pages/NFT/NFT_long.sol

在polygonscan上放的也是這個較長的程式碼檔案:

https://mumbai.polygonscan.com/address/0x8abb77ff22f8966729603bd49c5c049c4294efd5#code

------------------------------------------

contract NFT is ERC721, ERC721Enumerable, Ownable {

這一段讓合約NFT同時繼承三個合約,意思就是同時擁有這些合約中擁有的可繼承函數和變數

Ownable的功能實際上並沒有用到,ERC721Enumerable也可以不需要使用,這邊就只是照著範例去寫,因為加了也沒什麼問題所以就沒改掉了

------------------------------------------

string[] uriArr;

這個陣列用來儲存每個NFT的URI,後面會提到具體放的是什麼東西

一般的NFT通常是只儲存一個baseURI,在baseURI後面再加ID數字來轉換成各個NFT的URI,不過這裡讓使用者可以自由輸入自己想要的URI,所以用陣列存起來

------------------------------------------

constructor() ERC721("NFT Token", "NFT") {

}

這裡調用繼承的ERC721的建構子函數,意思是說合約NFT在產生時也會呼叫ERC721的建構子函數,如下:

(在https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/ERC721.sol 之中)

constructor(string memory name_, string memory symbol_) {
  _name = name_;
  _symbol = symbol_;
}

所以"NFT Token"代表這個合約所有NFT的共同名字,而"NFT"代表這個合約NFT的token符號

------------------------------------------

function mint(string memory uri) public {
  require(bytes(uri).length > 0);
  _safeMint(msg.sender, uriArr.length);
  uriArr.push(uri);
}

進行鑄造NFT,這邊只需要呼叫繼承的函數_safeMint(),以及把輸入的URI丟到陣列uriArr之中就好

注意其中第二個參數uriArr.length就代表這次鑄造的ID,換言之第一次鑄造會是ID=0、第二次鑄造會是ID=1,依此類推

------------------------------------------

function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
  require(tokenId < uriArr.length);
  return uriArr[tokenId];
}

tokenURI()是用來讀取NFT的ID對應的URI,OpenSea需要呼叫這個函數才會知道NFT的圖片網址在哪裡

------------------------------------------

function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal override(ERC721, ERC721Enumerable) {
  super._beforeTokenTransfer(from, to, tokenId);
}

function supportsInterface(bytes4 interfaceId) public view override(ERC721, ERC721Enumerable) returns (bool) {
  return super.supportsInterface(interfaceId);
}

這二個只要照著寫就好,內容只是呼叫繼承的上層合約的函數來用(super.),沒有其他特別的用意,不過沒寫的話會出現錯誤所以就寫進來了

------------------------------------------

接下來解釋NFT的URI是什麼,這次提供了4種不同的URI,依序進行解說:

1.正統的IPFS星際文件系統的網址格式,比如:ipfs://QmUtb97bLLNPYTYPzCPxuLhu3q4kRcMzhtrW7W5xJVgr9B

IPFS是一種網路檔案協議,可以為每一種內容不同的檔案分配一個獨一無二的網址,雖然目前並沒辦法保證檔案可以永久存在,但至少可以保證不會有內容不同的檔案共用同一個網址,所以被當作NFT這種需要永久儲存資料的建議檔案協議

這次使用的IPFS服務網站是https://www.pinata.cloud/ ,進行註冊後就可以免費上傳檔案來產生IPFS文件,不過免費版的會有流量上的限制要注意

當在裡面上傳檔案後(按下那個Upload按鈕然後選擇要上傳的檔案),網頁會給你一串代碼,比如QmUtb97bLLNPYTYPzCPxuLhu3q4kRcMzhtrW7W5xJVgr9B

把這個代碼加上ipfs:// ,就可以形成ipfs網址,也就是ipfs://QmUtb97bLLNPYTYPzCPxuLhu3q4kRcMzhtrW7W5xJVgr9B

不過這個網址沒辦法直接在一般瀏覽器上打開,如果想知道這個代碼對應的檔案內容,則需要加上「https://ipfs.io/ipfs/ 」,也就是 https://ipfs.io/ipfs/QmUtb97bLLNPYTYPzCPxuLhu3q4kRcMzhtrW7W5xJVgr9B

實際打開後我們會發現這個NFT的URI對應的檔案內容為:

{"name":"raBit","description":"raBit","image":"https://ipfs.io/ipfs/QmRThPPB1PEsS6tSKdQX4p2UDm8M1EVxDHrBvuTx9dnvFe"}

這個檔案為json檔,基本上就是記錄這個NFT的名字(name)、描述(description)、和圖片網址(image),實際上最重要的只有圖片網址,名字和描述都沒有也是可以顯示在OpenSea上

也就是說如果要製造自己的NFT,首先要上傳圖片,取得圖片網址https://ipfs.io/ipfs/QmRThPPB1PEsS6tSKdQX4p2UDm8M1EVxDHrBvuTx9dnvFe ,之後再建立一個json檔把這個NFT的資料存好,再把這個json檔上傳成ipfs文件,最後用json檔的ipfs網址來進行當作URI鑄造NFT

------------------------------------------

2.json檔的網址,比如:https://ipfs.io/ipfs/QmUtb97bLLNPYTYPzCPxuLhu3q4kRcMzhtrW7W5xJVgr9B

實際上不使用ipfs網址也可以,只要給一個網址,這個網址會給出json檔的檔案內容就可以

------------------------------------------

3.使用Data URI的格式來表示json檔,比如:

data:application/json;base64,eyJuYW1lIjoicmFCaXQiLCJkZXNjcmlwdGlvbiI6InJhQml0IiwiaW1hZ2UiOiJodHRwczovL2lwZnMuaW8vaXBmcy9RbVJUaFBQQjFQRXNTNnRTS2RRWDRwMlVEbThNMUVWeERIckJ2dVR4OWRudkZlIn0=

可以試著把上面這串文字複製到瀏覽器的網址輸入列上然後按下enter,會發現瀏覽器會自動顯示出之前的json檔的內容,這個技術叫作Data URI,也就是把資料弄成base64編碼的文字,然後在前面加上「data:application/json;base64,」就能讓瀏覽器視為json檔

把文字轉換成base64編碼可以使用這個網站:

https://www.base64encode.org/

想要解碼的話也可以用這個網站,可以把上面的那串編碼文字丟進去看看:

https://www.base64decode.org/

------------------------------------------

4.不只使用Data URI的格式來表示json檔,連本身包含的圖片資料也是用Data URI來表示,比如:

data:application/json;base64,eyJuYW1lIjoiaWNvbiIsImRlc2NyaXB0aW9uIjoiaWNvbiIsImltYWdlIjoiZGF0YTppbWFnZS9wbmc7YmFzZTY0LGlWQk9SdzBLR2dvQUFBQU5TVWhFVWdBQUFDZ0FBQUFvQ0FJQUFBQURuQzg2QUFBR3IwbEVRVlJZaGNXWWYzQlVWeFhIditmZTkvWlhOcHNmbXcwa0lWZ0lBWnFHMGdKU3RZMVd3SlpXclMyMmRPSkluYWwyT25XMFA5VFJEdTNvWUlkT2h4bFI2NHdqVXNmUkdhYlNPaTIyV29RSkZFUVVXeUFwTmlHUU5CUENralUvTm1HelNmYkhlKzhlLzNoaDgzYXorUUg5Zy9QUDIzZnZ1ZWR6enA1ejd6dnZFVFBqZW9pNEx0VHJDZGF1YVJXREdheGdwMGxJMEZVSGNCVmd4YXFqczdXOWFWZFo5TlQ4WkhjNTl3TVlKZitnWHRrYlhIdkQzZCt2WFZJdjV1d0J6VjVjek1sMDhyVTlQM3ZnbzUvTWF1N05tbTJidi81RGo4djFjY0VxRlQremZYT05kWEJXUXdBQkU2WU9OYng2MzkwUHpoejlUR0JsR2RGSFM3MWw0K3dCQUFnNWtkcXBWZ29yWk1WS2prZXN2bFlvRThDN25pOTg2ZmwzWm1CUEM0NE45TWtuS25uWnhLMG9XYVRWZnhWbXlqaXpsOGY2Si9XRTFHOSsySDN2VHZJVWNleGlZdS9YclBCSmU2YVhLaXFlYlF2NEExY0JWcXppajN0RXlKcFFjZ2U4alh2bGtnMGdvUWJheDNjMWNHTElucElMUCtWNzdDakVSSkVhcDM2ZmZPTmJHVHNSV1ZxN3JZL3l4WjFuU0xHS1BGV2VvUUlRd1NWeThaMzJuaEdoNWQ3R1AwSG90a3V1enp5Wm9RTFFGbjNXdWJVcXJLRWpQMi9nZk5uSkEyN1pmbCtnY05nNVF1N0NLeVFBa0RYclpQVmFBQ0JRMGNKc2V4cEF6b0UxMFJNbjJvN05EazZjYTZwTjdNOFE3WXVLUjJDbG5KN0lHKzRBQUdhcnM4bTUzTHJ3VHlBcnZyQUkvUEx0bDAyVkczUXV1T2NQendBZ3Fjc0ZuOVJ2YVpUelY1RFFPQlkyengrWVZGSVd4OEwyei9SN3U1Q09YOEdtVTBkZUFqTkpYWlF0bFZXcnlWdnNnN2s3dnE5ajk4WWNVTmJKWmZaOVdFbHRKRFI5N2VQdURUK0YyODlqMGRSYjN6YmI5cVgrL2lQeUZNbnF0V0JsdHYvVjZyaXlzeE5ENXZtRDJ2SXZBa2ovWTRjYU9Fc2t0QldiWFhkdUpjMWpudDhmUExDVlUxalFjOGpxYjVYbE4rVUhYenA5dUJTZzRtclhIYy9BVXdTQS9PV3VEZHZNemlZVjdVaTgrcEFJM1FoV3FyK05rN0VyVVJyR3lkMHdFeW9lU1ovNE5aZ3BVT20rNjBVcVdnQkFYL09vMlhIUVBQc1dnS0dlMDZIcHdBUEg5cFVTU0MrQTVzME1raThJNlFMQTQwTld6NytRdmYyWWxkVjFSRVUrWUNQQnFUZ0FFYXloUU1YRXRIUnJpejl2dGIvTnpCOTFIQSt0MlpKWm1KWGpvdEV1QU9yeUJhdXpDV3dCQUZ0VzV5Rms0bU1HaUtTTFBFVVVxSkxsTjRyaWhTQlNvLzAyMVhiVldkaHNqRTE0T25EV3ljcUt1RVFNQU9CVVBQbTNwL1ZJczF6ME9SWDVJUDN2WDdFeUFaQ1FWRmloMWQydjNiUkpGSDhDbWdkczhmaWdlZTRkNDczZmNpeHM3MWRPRENFVnR6TUZNMkcydm1uL1NjR3hpMDdXNU1tVmZuZDdxdW5IV1hNazJINzBBdVR5dTlZOXI2LzZCdm1DSU9sVUF5dE9ERnRkaDQzVGY3UzZqN0dRN28wNzlHWDNBR1Q4NXpmcG95OU4rSzE1ZkUrMmlHRHRsSWhGN3RiS25EaWtlejFmZmxtN2RVditCejRKOGdXMStvZTB1Z2RVNzZteEE4OFpoMSt3V3QvZ1pFeEZXbXlxSFFjNVVwQjFWa2VmOXJrS1VybG1TV2dyR3oyYlhyRkxiQlpoeTdwd1BQbmFJendTWnNCWmlmOHJYRno3Yk1ka21NNVZRNm84VHp5RjgxMjNQelVuS2dBU3BIbWdlNWc1cC82SC9OWE8yeXh3ekw5NHFpbFJYaWRLOG96bkY2VlVQTUlqa1N4bkFBQmN0c3c1bUFVT05kdy8xUlQ1Z3BCemJzMEk1QzBCT1hJSkVKaUFwWFVicGdWWHJWcVg1VDFMQUd3a2tDbVFPYkZGcGdadEtnQUlXVks3Zmxxd05xKytsK3N5dDVZTmprYzRQWjYzNDhranJOVGdlUmdKY2xLQmtSVmJ5RnM4TFJoQTlZTmJIYjREQU1kNjFIQTNsSkhwNVdiaUppNmIvLzB6VzJrNHFPVHlWV3g4SVVjekYreGIxZGp2dnkwTFBCWTFXL1p3Y2dTV09XUGNqUFNZY2ZJVnEvdW9NMVlRNmZmc3BFQmxqbmFlbmt1eDZubWlLaGpzVDhIalJoSUF1ZjJ1MjcrbnIzcUVDa0tRYnNqc05vTVZ6SVM2Zk5GNGY3ZHg4bmRJalRoYkVMbXkwYk41ejFRM3AyMzJtaDlic1hSZSs2U2U3aFdWdDJvMTYyWDFiU0pZQzNjaHJEU1A5SnFYTDJMd25IWHBmWFhwTkkvMlFSbFpqVTlnUWNFUE92T2VBZE8ydC9HMGNXajd2ZXZOdzFuYUpLQjd5RCtQQ2l1UUdsWERYV3draVpWOXVOcmJadEo3NlM3NGJyTUlMYzlyZjhhR1BoMC92blA5emZFV0FXczZuVWxEenJ3Q1VYZFoxVGYzeTZyVjArblA5SlloOUlKUFA3d2pGYXcxU2ViMGpqTkw3K3J2VkQ4WG5vR0syVi9hbU5Wd2QvckQxM3ViWHpjR3UwbzQ2ZWEwUVA3YUptQWdkRXZWVjM3aFd0UXdxM056ZUZzRXdJcFRJeXJhT1J4dWpwejVTL0RTQ1o4WlZ5d01na1lrQ0FKTUJTRlgvU2IzWFMrUzdwdmQ0RnpCVHJIU0toWldBMmQ1ZkJoRXBIdkpIWUN2VlBqblVVRm9yZyt4YXdGUGlyM3dLbkx2bEd2N0ZJR1BnN1RsdW4xOCtUK09KL05xbC9VbWlRQUFBQUJKUlU1RXJrSmdnZz09In0=

把上面這一串文字複製到瀏覽器的網址輸入列上然後按下enter,會發現瀏覽器顯示出這樣的json檔內容:

{"name":"icon","description":"icon","image":"data:image/png;base64,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"}

然後我們再把當中原本是圖片網址的那一串「data:image/png;base64,...==」文字再複製到瀏覽器的網址輸入列上然後按下enter,會發現瀏覽器顯示出TEST幣的圖標:

也就是說我們把圖片的資料檔案也用base64編碼轉換成文字,然後因為是png檔所以在前面加上「data:image/png;base64,」來形成Data URI,把這個圖片Data URI再放到json檔,這個json檔再轉換成Data URI,最後再使用這個URI就能進行NFT的鑄造了

這個方法可以把NFT的圖片資料全部上鏈,不用擔心NFT放在網站上的資料出問題,唯一的問題就是需要花費很多的gas費來把資料上鏈

而要把圖片檔轉換成base64編碼一樣可以使用這個網站:

https://www.base64encode.org/

下面有一個Encode files to Base64 format,可以上傳圖片檔來進行base64編碼

------------------------------------------

最後來說一下鑄造NFT網頁中是怎麼做到新增Mumbai鏈資料的,程式碼如下:

https://github.com/vcckvv/SmartContract/blob/gh-pages/NFT/index.html

async function switchMumbai(){
	try{
		await window.ethereum.request({method: 'wallet_switchEthereumChain', params: [{ chainId: '0x13881' }],});
	}catch(err){
		if(err.code == 4902){//has not been added to MetaMask
			const chainData = [{
			    chainId: '0x13881',
			    chainName: 'Mumbai',
			    nativeCurrency:{
			    	name: 'MATIC',
			    	symbol: 'MATIC',
			    	decimals: 18
			    },
			    rpcUrls: ['https://matic-mumbai.chainstacklabs.com'],
			    blockExplorerUrls: ['https://mumbai.polygonscan.com/'],
			}];
			
			try{
				await window.ethereum.request({method: 'wallet_addEthereumChain', params: chainData,});
			}catch(err2){
				alert(err2.message);
			}
		}
		else{
			alert(err.message);
		}
	}
}

這個函數是先試著切換到Mumbai鏈,如果失敗的話就看錯誤碼是否為4902,是的話就代表還沒有這個鏈的資料,於是我們再使用await window.ethereum.request({method: 'wallet_addEthereumChain', params: chainData,});來新增Mumbai鏈的資料,chainData中包含了Mumbai鏈所有需要的資料

------------------------------------------

這次的解說就到這裡,下次要來實作NFT去中心化交易所,敬請期待~

1
$ 0.00
Avatar for vcckvv
Written by
1 year ago

Comments