如何在NFT(ERC721)中獲取隨機數

2020-12-11 金色財經區塊鏈

介紹

在遵循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

相關焦點

  • C語言/C++中如何產生隨機數
    需要說明的是,iostream頭文件中就有srand函數的定義,不需要再額外引入stdlib.h;而使用time()函數需要引入ctime頭文件。使用rand()函數獲取一個隨機數如果你只要產生隨機數而不需要設定範圍的話,你只要用rand()就可以了:rand()會返回一隨機數值, 範圍在0至RAND_MAX 間。
  • ICO在中國已死,區塊鏈下一個機會是ERC-721
    區塊鏈3.0將如何在中國爆發?這是今天這篇文章想和大家掰扯的。簡短的回答是物理和虛擬世界資產上鏈,粗魯的回答是ERC-721(以及與721使命類似的非標代幣通證,對被代表的NEO等說抱歉)。以太坊的ERC-20標準我天天聽得耳朵磨繭子,ERC-721是個啥?我們還要從ICO1.0和ERC-20掰扯起。
  • 區塊鏈的下一個機會不是ICO2.0,而是ERC-721
    最初這是由一群極客築起的伊甸園,卻逐漸歸於一個關於財富、欲望、野心、權利、焦慮的人間大戲,在這個數字世界裡穿越了財富階級,穿越了人們獲取財富的時間路徑、穿越了物理空間已經成為一場全球化戰役,在多維度的解構和重構下,所說的「幣圈一天,地上一年」,幣圈和鏈圈正在以分鐘為時間單位快速進化和變異,誰都想在一片混沌之中爭得一席之地。
  • Untitled NFT黑客松完整回顧
    原文連結:https://medium.com/nfthack/untitled-nft-hackathon-submissions-71bb7d686dcc作者:Peter 『pet3rpan』譯者:Weiwei翻譯機構:DAOSquare  我們希望你能在最近一月中有時間啟動一個新項目。
  • 如何在單片機中生成隨機數
    隨機數在單片機的應用中也是很多的,當然產生隨機數的方法有很多,當中有一個就是利用單片機定時器,取出未知的定時器THX和TLX的值,再加以運算得到一個規定範圍內的隨機數值。
  • 區塊鏈中隨機數的實現
    當我們談論計算機系統中的隨機性時,我們真正指的是偽隨機性,即儘可能模擬出現實世界應有的隨機性,使之近乎於「真正的隨機性」。以密碼學安全偽隨機數生成器為例,這是一個非常強大的隨機性模擬。隨機數在隱私技術和密碼學中發揮著重要作用。令人驚豔的是,通過生成一個隨機數來對一條消息進行運算(XOR),提供了一種簡單但十分強大的加密方案。
  • 如何利用代碼生成一個隨機數?
    這個數字會被③步驟中的成員方法獲取到。⑤列印這個數字。二、Random類Random,翻譯成中文就是「隨機的」的意思。顧名思義,也就是說通過這個類,可以獲取一個隨機數。Random是一個工具類,是Java已經存在的一個類,不需要我們自己再去建一個類,直接調用就可以了。步驟:①import導包(Random工具類)。
  • 單片機C語言如何產生隨機數?
    隨機數在單片機的應用中也是很多的,當然產生隨機數的方法有很多,當中有一個就是利用單片機定時器,取出未知的定時器THX和TLX的值,再加以運算得到一個規定範圍內的隨機數值,這種做法也是可行的;或者預先寫好一個隨機數表,然後從表中取數據也是可以的。
  • Excel生成隨機數的技巧,隨機數發生器,你用過嗎
    Excel獲取隨機數從概率分布中產生隨機樣本,其基本原理是隨機數的概念。隨機數是均勻分布在0和1之間的數。從技術上講,電腦不能產生真正的隨機數,因為它們必須使用一個可預測的算法。但是,設計用於產生一個數列的算法,似乎是隨機的。在 Excel中,我們可以使用函數RAND()在任何一個單元格之中產生隨機數。
  • python中的隨機數
    random模塊是python中的隨機數模塊,也是比較常用的模塊之一。
  • C++入門基礎系列:走進信息學奧賽,如何產生隨機數?
    目標:爭取在普及組複賽中做出1道題。進入本文的主題:C++中,如何產生隨機數?02如何產生隨機數?分三步驟,第1、2步為固定語法格式;第3步根據題目具體要求編寫表達式。03案例一:產生一個0-10之間的隨機數rand()函數會產生一個隨機數,但並沒有確定範圍。如何獲取一個給定範圍的隨機數呢?在這段代碼中,只需要讓rand()函數取10的餘數,即可得到一個小於10之內的整數。注意:頭文件、產生隨機種子代碼的編寫。
  • 錯過了Defi的爆富浪潮.千萬不要錯過NFT百度遊戲萊茨狗爆發的前夜
    此圖為狗狗形象,狗狗的唯一ID編號,所屬者,以及八個屬性簡述一下自己會如何結緣NFT賽道的?當我發現全球區塊鏈行業飛速發展的時候,我選擇了加入這個行業,選擇加入百度區塊鏈的原因是因為,我本身就是百度的忠實粉絲,當聽說百度布局區塊鏈以後,毫不猶豫的加入進來,當時百度2018年二月份發布了第一款區塊鏈應用遊戲萊次狗,我就深的喜歡上了這個遊戲,隨著今年defi的火爆發展,Nft正在悄悄醞釀,我覺得來次狗會是今年一個非常大的爆發年,所以我們選擇了去中心化的nft作為發展方向
  • 如何使用javascript生成6位隨機數
    網頁中有很多獲取手機驗證碼的例子,這裡我們來做一個假的例子。用最基本的js去寫,實現的效果是點擊獲取驗證碼碼按鈕,生成6位隨機數。首先新建一個測試網頁,裡面沒有什麼多餘的內容。在網頁中寫一個label  input框 一個按鈕。預覽一下效果。
  • 隨機數大家都會用,但是你知道生成隨機數的算法嗎?
    再不濟我們每周的抽獎都是用隨機數抽出來的,我們用隨機數的時候,往往都會加一個前綴,說它是偽隨機數,那麼這個偽隨機數的偽字該怎麼解釋,什麼又是真隨機數呢?計算機算法得出的各種隨機數之所以是偽隨機數是因為它們的結果都是可以預測的,只要我們知道算法和起始狀態以及各種參數,就可以預測下一次隨機出來的結果。而真隨機數則無法預測,就是純粹隨機的。但問題來了,拋硬幣和擲骰子這些物理現象又是真的隨機嗎?如果我們知道了硬幣的起始狀態以及拋擲的角度和力度,是不是可以預測硬幣拋擲的結果呢?
  • 玩轉Python 中的隨機數
    開發中我們經常遇到需要隨機數的場景,比如為了用戶密碼更安全我們有時會加鹽,也就是將用戶原密碼連接上一串隨機字符然後加密保存,又比如我們可能需要隨機展示某張圖片等等。今天,我們就來理一理 Python 中的隨機數的玩法,當然,這裡只涉及標準庫。
  • 隨機數本質,C語言的隨機數與隨機種子
    引言在實際編程中,我們經常會用到隨機數這個概念,其實也是一個偽隨機數,實際上並不是一個真正的隨機數,但是也足夠我們使用了。在C語言中,編寫一些關於遊戲之類的程序時就需要用到隨機數了。@雲主宰蒼穹—正態分布生成隨機數在C語言中,我們一般使用 <stdlib.h> 頭文件中的 rand() 函數來生成隨機數,它的用法為
  • laravel高性能地從mysql資料庫中隨機獲取n條數據
    laravel如何高性能地從mysql資料庫中隨機獲取n條數據,有時候我們常常會需要從資料庫隨機獲取數據,比如:給工作人員隨機分配10個訂單,隨機從資料庫中隨機抽查100個用戶;這樣我們就需要隨機從資料庫獲取數據。
  • 淺談Java中的幾種隨機數
    眾所周知,隨機數是任何一種程式語言最基本的特徵之一。而生成隨機數的基本方式也是相同的:產生一個0到1之間的隨機數。看似簡單,但有時我們也會忽略了一些有趣的功能。我們從書本上學到什麼?最明顯的,也是直觀的方式,在Java中生成隨機數隻要簡單的調用:java.lang.Math.random() 在所有其他語言中,生成隨機數就像是使用Math工具類,如abs, pow, floor, sqrt和其他數學函數。
  • 利用隨機數完成公司年會抽獎過程
    大家好,最近推出的內容是「VBA信息獲取與處理」中的部分內容,這套教程面向中高級人員,涉及範圍更廣,實用性更強,現在的內容是第二個專題「隨機數(Random)在EXCEL工作表及VBA中的應用」的內容。s對於數據處理而言,隨機信息的處理是非常重要的一部分,什麼是隨機數呢?隨機數是專門的隨機試驗的結果。
  • 在EXCEL中隨機函數的利用
    大家好,最近推出的內容是「VBA信息獲取與處理」中的部分內容,這套教程面向中高級人員,涉及範圍更廣,實用性更強,現在的內容是第二個專題「隨機數(Random)在EXCEL工作表及VBA中的應用」的內容。對於數據處理而言,隨機信息的處理是非常重要的一部分,什麼是隨機數呢?隨機數是專門的隨機試驗的結果。