介紹
在遵循ERC721標準的非同質化代幣(NFT)中生成隨機數一直是智能合約開發者面臨的難題。現在,Chainlink VRF已經在主網上線,基於Solidity的智能合約可以無縫生成防篡改的鏈上隨機數,這些隨機數可以證明是公平的,並且有密碼學證明支持。有了Chainlink VRF,創建需要安全隨機性來源的動態NFT變得非常簡單、安全。雖然Chainlink也可以使用鏈外數據源為NFT實現任何類型的動態屬性,但我們將專注於使用ERC721的隨機數,或NFT。
在本教程中,我們將在以太坊區塊鏈上構建一個龍與地下城角色!D&D(Dungeons and Dragons)是一款流行的角色扮演遊戲(RPG),人們在遊戲中創建角色並進行冒險。創建角色的重要環節之一是給他們賦予屬性或統計數據,以顯示他們的力量、敏捷、智力等。為了在區塊鏈上為他們的統計數據創建真正的隨機數,我們將展示如何使用Chainlink VRF給你的角色隨機屬性。使用Chainlink VRF,區塊鏈中的隨機數生成很簡單!
什麼是NFT?
NFT(遵循ERC721標準)定義了一個框架,用於製作獨一無二且彼此不同的代幣(因此被稱為非同質化),而流行的ERC20標準則定義了 "同質化 "的代幣,這意味著代幣都可以互換,並保證具有相同的價值。"同質化 "貨幣的例子是美元、歐元和日元,而可互換區塊鏈代幣的例子是AAVE、SNX和YFI。在這些情況下,1個同質化的代幣等於1個同類的另一個代幣,就像1美元等於1美元,1LINK等於1LINK一樣。然而,NFT/ ERC721是不同的,因為每個代幣都是獨一無二的,並不代表相同的價值或可互換的項目。
由於所有的NFT都是獨一無二的,它們可以代表現實世界資產的代幣化所有權要求,如一塊特定的土地,或數字資產的實際所有權,如稀有的數字交易卡。而且它們越來越受歡迎。你可以參考OpenSea的NFT聖經來閱讀更多內容。
構建你的隨機角色
我們要看的是創造一個具有D&D角色六大屬性的角色,即:
uint256 strength;
uint256 dexterity;
uint256 constitution;
uint256 intelligence;
uint256 wisdom;
uint256 charisma;
角色還包含:
uint256 experience;
string name;
所以我們可以把它們的等級提高,並給它們起一個有趣的名字。
我們在這裡採取了一些自由的做法,並沒有100%遵循龍與地下城的指導,但如果你想更準確地表現遊戲,這可以很容易地修改。
這份合約應該確立以下內容:
1. 允許你轉讓NFT的所有權 和所有其他NFT標準。
2. 給這個角色一個名字和隨機屬性。
我們不去製作合約的動態,但請繼續關注未來的一篇文章,它將在我們在這裡學到的知識的基礎上構建!
我們已經為你建立了代碼倉庫,我們將介紹如何使用代碼倉庫開始工作!
克隆代碼
git clone https://github.com/PatrickAlphaC/dungeons-and-dragons-nft
cd dungeons-and-dragons-nft
npm install
設置環境變量
你需要一個`MNEMONIC`和一個rinkeby網絡的 `RINKEBY_RPC_URL`環境變量。`MNEMONIC`是你的錢包的助記詞。你可以從節點提供者服務中找到一個`RINKEBY_RPC_URL`,比如Infura。
然後,要麼在`bash_profile`文件中設置它們,要麼將它們導出到你的終端,比如:
export MNEMONIC='cat dog frog....'
export RINKEBY_RPC_URL='www.infura.io/YOUR_PROJECT_ID_HERE'
代碼目錄中有什麼
目錄中有我們所有的模板代碼,但真正的魔法是在`DungeonsAndDragonsCharacter.sol`文件中。我們可以看到它開始時是一個普通的Solidity文件,但我們在頂部有一些導入:
pragma solidity ^0.6.6;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@chainlink/contracts/src/v0.6/VRFConsumerBase.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/Strings.sol";
contract DungeonsAndDragonsCharacter is ERC721, VRFConsumerBase, Ownable {
是一個包的集合,它讓Solidity和智能合約工程師的開發工作變得更輕鬆。如果你之前沒有用過它,那就準備好多用它吧! 由於ERC721隻是一個代幣標準,每一個ERC721應該都差不多,所以我們知道我們可以用一個模板就可以了。我們導入的`ERC721.sol`文件定義了一個NFT的所有標準。我們只要在合同中繼承它,定義`contract DungeonsAndDragonsCharacter is ERC721`。我們需要`VRFConsumerBase.sol`來與Chainlink VRF交互,並獲得隨機數。最後兩個導入只是幫助我們處理權限和與字符串的工作。
角色結構體和構造函數
在Character結構體中定義了我們的角色將具有的屬性,並且製作了一個角色列表,這樣就可以跟蹤每一個被創建的角色。由於我們使用數組來存儲字符列表,每個字符在數組中都會有一個唯一的 ID 來定義它。這就是所謂的`tokenId`,我們將更多地引用它。
struct Character {
uint256 strength;
uint256 dexterity;
uint256 constitution;
uint256 intelligence;
uint256 wisdom;
uint256 charisma;
uint256 experience;
string name;
}
Character[] public characters;
定義好之後,我們可以創建構造函數。
constructor()
public
VRFConsumerBase(VRFCoordinator, LinkToken)
ERC721("DungeonsAndDragonsCharacter", "D&D")
{
keyHash = 0x2ed0feb3e7fd2022120aa84fab1945545a9f2ffc9076fd6156fa96eaff4c1311;
fee = 0.1 * 10**18; // 0.1 LINK
}
對應傳入`VRFConsumerBase`和ERC721參數。Chainlink VRF需要VRF協調器地址和LinkToken地址。我們已經在Rinkeby網絡中硬編碼這些地址了。還有一些其他變量為Chainlink VRF定義,比如keyHash和fee。你可以在Chainlink VRF文檔中閱讀更多關於這些變量的作用。`ERC721("DungeonsAndDragonsCharacter", "D&D")`這一行定義了NFT的名稱,然後是它的代幣符號。`"D&D"`將是MetaMask和NFT市場中顯示的內容。
生成你的隨機字符
我們希望角色的六個屬性中的每一個都有隨機統計,但我們希望能夠自己決定角色的名字!一個簡單的調用Chainlink VRF允許我們在這個NFT / ERC721中生成隨機數。在我們的請求函數中,不需要做太多的事情,只需要給新的角色一個名字,和一個`userProvidedSeed`。我們給它的種子是用來給VRF協調器驗證所提供的數字是否真的是隨機的。你可以選擇任何你喜歡的種子,你可以閱讀關於選擇隨機種子的文章來了解更多。
function requestNewRandomCharacter(
uint256 userProvidedSeed,
string memory name
) public returns (bytes32) {
require(
LINK.balanceOf(address(this)) >= fee,
"Not enough LINK - fill contract with faucet"
);
bytes32 requestId = requestRandomness(keyHash, fee, userProvidedSeed);
requestToCharacterName[requestId] = name;
requestToSender[requestId] = msg.sender;
return requestId;
}
我們要跟蹤`requestId`,這樣當隨機數獲取到時,我們就可以把它映射到我們正在創建的角色上。這將啟動Chainlink Job,需要等待Chainlink節點回調到我們的合約即可!你可以在Chainlink文檔中閱讀更多關於請求模型的內容,了解更多關於發送Chainlink請求的工作原理。
Chainlink節點完成了對請求的處理,它就會通過調用 `fulfillRandomness` 函數來響應。這個函數包含了給出屬性的計算,將角色添加到列表中,以及鑄造NFT。
function fulfillRandomness(bytes32 requestId, uint256 randomNumber)
internal
override
{
uint256 newId = characters.length;
uint256 strength = ((randomNumber % 100) % 18);
uint256 dexterity = (((randomNumber % 10000) / 100) % 18);
uint256 constitution = (((randomNumber % 1000000) / 10000) % 18);
uint256 intelligence = (((randomNumber % 100000000) / 1000000) % 18);
uint256 wisdom = (((randomNumber % 10000000000) / 100000000) % 18);
uint256 charisma = (((randomNumber % 1000000000000) / 10000000000) %
18);
uint256 experience = 0;
characters.push(
Character(
strength,
dexterity,
constitution,
intelligence,
wisdom,
charisma,
experience,
requestToCharacterName[requestId]
)
);
_safeMint(requestToSender[requestId], newId);
}
可以看到,只是用一次隨機數來創建所有六個屬性。使用取模運算對返回的大隨機數取一個子集。如果我們不想這樣做,我們也可以直接調用Chainlink VRF六次,但這種方式的效果是一樣的。返回的隨機數的最後兩位數字用於強度,前面的兩位數字用于敏捷,以此類推。這與CryptoKitties使用基因給貓咪賦值的方式類似。
*需要注意的是:做位操作會比我們這裡的方式更有效率,但這樣更容易理解,所以我們不必去研究位操作的工作原理。*
`_safeMint`是繼承自`ERC721.sol`的函數,它允許我們跟蹤ERC721的所有者。這一點很重要,特別是當你希望你的NFT採取一些行動,但你不希望其他人能夠採取這種行動。我們將在下一篇NFT文章中了解更多的信息。
我們將使用Truffle和Chainlink,所以如果你不熟悉Truffle,這篇關於[如何使用Chainlink With Truffle的博文](將給你一個複習的機會,但我們也會在這篇博文中介紹所有的命令!
部署和快速啟動
現在我們知道是怎麼回事了,讓我們來部署我們的隨機NFT吧!你需要一些Rinkeby LINK和Rinkeby ETH來運行這些腳本。
truffle migrate --reset --network rinkeby
truffle exec scripts/fund-contract.js --network rinkeby
truffle exec scripts/generate-character.js --network rinkeby
truffle exec scripts/get-character.js --network rinkeby
上述命令做了下面這些事情:
1. 部署NFT合約
2. 向合約注資以便可以發起Chainlink VRF調用
3. 用Chainlink VRF調用生成角色
4. 返回NFT值
部署完畢,你還可以驗證合約,甚至可以使用etherscan插件在Etherscan上閱讀合約。你需要獲得一個Etherscan API密鑰,並設置環境變量`ETHSCAN_API_KEY`。之後運行:
truffle run verify DungeonsAndDragonsCharacter --network rinkeby --license MIT
然後它會給你一個Etherscan上的NFT連結。你可以在Etherscan上閱讀合約內容。
這樣你就進入到可以與合約互動的頁面。如果你進入角色部分,你可以輸入我們剛剛生成的tokenId,0,然後就可以看到你的新D&D角色的統計信息了。
你可以查看Rinkeyby的這個合約的例子。其中有幾個角色的名字很有意思!
總結
使用Chainlink VRF在NFT中隨機數很容易,使用之後會有一個全新的世界可以探索。我們在這裡只是觸及到了表面,所以請期待下一篇關於在市場上銷售它們、渲染圖像和使用元數據的博客。我們很想看到一些使用Chainlink VRF創建的很棒的角色和遊戲,為它們提供動力,做到真正公平。如果你打造了一款酷炫的NFT #PoweredByChainlink,一定要在推特上告訴我們!
如果你是一名開發者,並希望將你的智能合約連接到鏈外數據和系統,請訪問開發者文檔並加入Discord上的技術討論。如果你想安排一個電話,更深入地討論整合問題,請在這裡聯繫我們。
智能合約開發者正在NFT中建設一個全新的隨機世界。你會成為引領這一潮流的先驅者之一嗎?
本文來源: 金色財經 / 作者:Chainlink