我有提到自己比較喜歡以「project」為導向來學習新的語言或是各種知識,換句話說就是動手做增強自己的肌肉記憶,同時也訓練尋找解決方法的能力。
因此我決定拿這個系列文來分享我開發一個 project 整體流程,這樣不僅可以讓我學會很多東西、加強我對 DApp 開發的能力,同時也可以記錄我在做這些 project 中遇到的一些困難以及是如何解決的。
此篇會拿來介紹第一個 project,並將他 breakdown 成不同的部分討論,以及目前想到要如何做這個 project 與需要學習的東西。(撰寫此篇文時我已經學完前端三巨頭:html、css & js 和一些基礎的 solidity 語法,僅供讀者參考)
我在初步理解了 NFT 的功能後,阿陸(my mentor)建議可以做一個關於 「做一個可以驗證 ERC1155 的系統」,於是開始有了這個 project 的初步構想。
假設一個場景,若今天你是奧運的主辦方,你想要使用 NFT 當作入場的憑證,如在入口處設置一個自動化的掃瞄機器,掃描過後呈現 valid 才會開門。
但是在奧運中進出的人員有很多,有工作人員(又可以分為各種團隊:攝影、裁判、紀錄、場邊的協助人員、義工)、運動員、運動員旁的工作人員如運動防護員、救護員、教練團、經紀人、觀眾等。這時便可以(或者最適合)使用 ERC1155 這個協議而非 ERC721 當作憑證(下面會提到)。
各種人員得到他們的 NFT 之後,會利用 NFT 的 tokenId 將他們持有的 NFT 轉成 QR code,或是其他形式的掃瞄證明。而在路口處面可以利用掃 QR code 來驗證這些人是否真實持有這些憑證。
持有的NFT >>>>
如果目前還不了解 ERC721 與 ERC1155 可以看看下面的兩張圖,會大致上提一下 ERC721 與 ERC1155 在這個例子中的不同,但是我也會在之後的文章中更仔細地介紹這兩個協議。
首先在 ERC721 的協議中,每一個 NFT 都是不同的,也就是說,每一張 NFT 都是一個獨一無二的存在。這也是為何 ERC721 的 token 可以作為憑證的原因。
若我們使用 ERC721 來作為奧運工作人員的憑證的話,可能會有以下幾個問題:
1. 觀眾與工作人員進出的門不一樣,如何讓系統得知你的身分是誰?
由於在 ERC721 的協議中每一張 NFT 都是相同的,但是每一張 NFT 都是獨一無二的。其實這個問題也有其他解決方法,例如工作人員的 NFT 的合約與觀眾的合約分兩個來 deploy,接著去一個一個驗證:
let contract = ["0x...00", "0x...01"] // 00: 工作人員 01: 觀眾
let QRcode = "NFT 的資料"
for (let i = 0; i < contractAmount; i++){
if (QRcode.contract == "0x...00"){
certificateWorkers(QRcode, tokenOwner);
}
else{
certificateSpectators(QRcode, tokenOwner);
}
}
// certification() 中就會呼叫鏈上的資料並進行驗證
2. 工作人員又可以分成很多個職位,要怎麼區分這些職位的人?
其實這個問題跟上個類似,只是又更複雜了。例如工作人員至少可以分成五類,如果我們用類似上面的做法就會消耗很多的時間,因為你還需要從鏈上取得 NFT 的資料;此外這個系統區別工作人員時需要將遍歷不同的合約來確認是哪一個合約,實施上效率也不太適合。
但是使用 ERC1155 這個協議便可以解決上述的幾個問題。
ERC1155 有點像是把 ERC20 (fungible token) 與 ERC721 (non-fungible token) 結合在一起。 簡單來說,他同時可以保有 ERC721 與 ERC20 的特性。
拿遊戲來舉例,打怪掉的道具可以就是一種 ERC1155 的 token。
事實上 ERC1155 在 EIP 中的名稱被稱為 「Multi Token Standard」,相較於 ERC721,他可以將自己的一些特性儲存在 metadata(未來會介紹到)上面,每類 NFT 的供給量。因為上述的這些特性,我認為 ERC1155 會是目前最適合拿來做這個專案的代幣協議。
這部分稍微有點複雜,會分成幾個 part 來討論。
首先需要先讓不同的工作人員或是觀眾選擇他們的身分別,再進行登入,簡單說沒有辦法一鍵 Mint 後便可以直接得到他們的身分別(目前我沒有想到其他的解決方法)。大致上長得像下面這樣。
系統會依照使用者選擇的身分自行選擇使用者會 mint 到的 NFT 是哪一種,但是目前的實際做法我還沒有頭緒。
接下來的部分會稍微比前面複雜的地方,可能需要一點點點點密碼學的概念來做驗證。
首先,前端會得到掃描 QR code 後傳入的使用者的 address。產生 QR code 的部分,首先需要使用者先登入自己的錢包,登入後,直接使用錢包的 address ,在使用者介面中呼叫產生 QRcode 的 API,將 address 轉換成 QR code 後在使用者介面中顯示。
但是在轉換前,我們需要先將這串 address 做加密的動作,例如:
let address = "0x...123"; // user address
let prime = 29;
const encode = (n, p) => {
n = n * p - 3;
};
encode(address, prime);
這時我們可以知道,因為使用者理論上是無法看到前端中寫了些什麼東西,所以他們無法透過將正確處理過的 address 轉換成 QR code,而是要利用原系統提供的方式轉換。
再加密之後,我們進行 QR code 掃描,再傳入系統之後會得到一串加密後的數字,這串數字可以透過我們的解密 function 解開,得到使用者原本的 address。
若使用者直接傳入由地址轉成的 QR code 便會無法解密
let fetchData = SOMETHING_ACCESS_FROM_THE_QRCODE
const decode = (data) => {data = (data + 3) / p;}
decode(fetchData);
const verfication = (decodedData) => {
return decodedData === address ? true : false
};
verfication(fetchData);
整體驗證的邏輯大概長這樣,但是最後實際做起來一定會長得跟上面不太一樣。而最後我們就可以利用呼叫 web3.js 等方式,抓取鏈上資料,例如 balanceOf()
等函式來驗證這個 address 中持有的 NFT 是哪一張了。
我認為這個專案可以讓我學到非常多東西。包含撰寫一張 ERC1155 合約、deploy 的方法、測試、了解在前端呼叫 API 的方法、驗證加密解密的方式等。應該會是一個不錯的學習的專案,在未來幾天中會分享我在專案中學習到的知識與遇到的一些問題和我是如何解決的!
若有文章內有任何錯誤的地方歡迎指點與討論!非常感謝!
歡迎贊助窮困潦倒大學生
0xd8538ea74825080c0c80B9B175f57e91Ff885Cb4