新聞中心
在本文中,我們將學(xué)習(xí)如何使用 Brownie、Python 和 Chainlink 來制作非同質(zhì)化的 NFT 作品,并在 OpenSea NFT 市場上展示和銷售我們的成果。在學(xué)習(xí)本文前,請閱讀用 Python 制作 NFT 區(qū)塊鏈作品(上)。

目前創(chuàng)新互聯(lián)已為上1000+的企業(yè)提供了網(wǎng)站建設(shè)、域名、虛擬主機、網(wǎng)站托管、服務(wù)器租用、企業(yè)網(wǎng)站設(shè)計、德化網(wǎng)站維護等服務(wù),公司將堅持客戶導(dǎo)向、應(yīng)用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長,共同發(fā)展。
動態(tài)和高級 NFT
動態(tài) NFT 是可以隨時間變化的 NFT,或者具有我們可以用來相互交互的鏈上功能。這些 NFT 可以無限定制,讓我們可以制作整個游戲、元宇宙(metaverse)或某種互動藝術(shù)。下面我們進入高級部分。
高級快速入門
確保您的metamask中有足夠的測試網(wǎng) ETH 和 LINK,然后運行以下命令:
- brownie run scripts/advanced_collectible/deploy_advanced.py --network rinkeby
- brownie run scripts/advanced_collectible/create_collectible.py --network rinkeby
我們的收藏品是從 Chainlink VRF 返回的隨機犬種。Chainlink VRF 是一種獲得可證明隨機數(shù)的方法,因此我們的 NFT 真正稀缺。然后我們想要創(chuàng)建它的元數(shù)據(jù)。
- brownie run scripts/advanced_collectible/create_metadata.py --network rinkeby
然后我們可以選擇將此數(shù)據(jù)上傳到 IPFS,以便我們可以擁有一個 tokenURI。稍后我會告訴你如何做到這一點。現(xiàn)在,我們將僅使用以下示例 tokenURI:
- https://ipfs.io/ipfs/Qmd9MCGtdVz2miNumBHDbvj8bigSgTwnr4SbyH6DNnpWdt?filename=1-PUG.json
如果您將 IPFS Companion 下載到您的瀏覽器中,您可以使用該 URL 來查看 URI 返回的內(nèi)容。它看起來像這樣:
- {
- "name": "PUG",
- "description": "An adorable PUG pup!",
- "image": "https://ipfs.io/ipfs/QmSsYRx3LpDAb1GZQm7zZ1AuHZjfbPkD6J7s9r41xu1mf8?filename=pug.png",
- "attributes": [
- {
- "trait_type": "cuteness",
- "value": 100
- }
- ]
- }
然后我們可以運行我們的 set_tokenuri.py 腳本:
- brownie run scripts/advanced_collectible/set_tokenuri.py --network rinkeby
我們會得到這樣的輸出:
- Running 'scripts/advanced_collectible/set_tokenuri.py::main'...
- Working on rinkeby
- Transaction sent: 0x8a83a446c306d6255952880c0ca35fa420248a84ba7484c3798d8bbad421f88e
- Gas price: 1.0 gwei Gas limit: 44601 Nonce: 354
- AdvancedCollectible.setTokenURI confirmed - Block: 8331653 Gas used: 40547 (90.91%)
- Awesome! You can view your NFT at https://testnets.opensea.io/assets/0x679c5f9adC630663a6e63Fa27153B215fe021b34/0
- Please give up to 20 minutes, and hit the "refresh metadata" button
我們可以點擊給出的鏈接,看看它在 Opensea 上的樣子!您可能需要點擊刷新元數(shù)據(jù)按鈕并等待幾分鐘。
隨機品種
然我們看一下剛剛做了什么。這是我們的 AdvancedCollectible.sol:
- pragma solidity 0.6.6;
- import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
- import "@chainlink/contracts/src/v0.6/VRFConsumerBase.sol";
- contract AdvancedCollectible is ERC721, VRFConsumerBase {
- uint256 public tokenCounter;
- enum Breed{PUG, SHIBA_INU, BRENARD}
- // add other things
- mapping(bytes32 => address) public requestIdToSender;
- mapping(bytes32 => string) public requestIdToTokenURI;
- mapping(uint256 => Breed) public tokenIdToBreed;
- mapping(bytes32 => uint256) public requestIdToTokenId;
- event requestedCollectible(bytes32 indexed requestId);
- bytes32 internal keyHash;
- uint256 internal fee;
- uint256 public randomResult;
- constructor(address _VRFCoordinator, address _LinkToken, bytes32 _keyhash)
- public
- VRFConsumerBase(_VRFCoordinator, _LinkToken)
- ERC721("Dogie", "DOG")
- {
- tokenCounter = 0;
- keyHash = _keyhash;
- fee = 0.1 * 10 ** 18;
- }
- function createCollectible(string memory tokenURI, uint256 userProvidedSeed)
- public returns (bytes32){
- bytes32 requestId = requestRandomness(keyHash, fee, userProvidedSeed);
- requestIdToSender[requestId] = msg.sender;
- requestIdToTokenURI[requestId] = tokenURI;
- emit requestedCollectible(requestId);
- }
- function fulfillRandomness(bytes32 requestId, uint256 randomNumber) internal override {
- address dogOwner = requestIdToSender[requestId];
- string memory tokenURI = requestIdToTokenURI[requestId];
- uint256 newItemId = tokenCounter;
- _safeMint(dogOwner, newItemId);
- _setTokenURI(newItemId, tokenURI);
- Breed breed = Breed(randomNumber % 3);
- tokenIdToBreed[newItemId] = breed;
- requestIdToTokenId[requestId] = newItemId;
- tokenCountertokenCounter = tokenCounter + 1;
- }
- function setTokenURI(uint256 tokenId, string memory _tokenURI) public {
- require(
- _isApprovedOrOwner(_msgSender(), tokenId),
- "ERC721: transfer caller is not owner nor approved"
- );
- _setTokenURI(tokenId, _tokenURI);
- }
- }
我們使用 Chainlink VRF 從 PUG、SHIBA_INU、BRENARD 列表中創(chuàng)建一個隨機品種。當(dāng)我們這次調(diào)用 createCollectible 時,我們實際上向鏈下的 Chainlink VRF 節(jié)點發(fā)起了一個請求,并返回一個隨機數(shù),以使用這 3 個品種之一創(chuàng)建 NFT。
在你的 NFT 中使用真正的隨機性是創(chuàng)造真正稀缺性的好方法,使用 Chainlink oracle 隨機數(shù)意味著你的數(shù)字可以證明是隨機的,并且不會受到礦工的影響。
您可以在文檔中了解有關(guān) Chainlink VRF 的更多信息。
https://docs.chain.link/docs/chainlink-vrf/
Chainlink 節(jié)點通過調(diào)用 fulfillRandomness 函數(shù)進行響應(yīng),并根據(jù)隨機數(shù)創(chuàng)建收藏品。然后我們?nèi)匀恍枰{(diào)用 _setTokenURI 來為我們的 NFT 提供它需要的外觀。
我們沒有在這里給出我們的 NFT 屬性,但屬性是讓我們的 NFT 進行交互的好方法。您可以在此 龍與地下城示例中看到具有屬性的 NFT 的一個很好的示例。
https://github.com/PatrickAlphaC/dungeons-and-dragons-nft
來自 IPFS 的元數(shù)據(jù)
我們使用 IPFS 來存儲兩個文件:
- NFT 的形象(哈巴狗形象)
- tokenURI 文件(JSON 文件,其中還包含圖像的鏈接)
我們使用 IPFS 是因為它是一個免費的去中心化平臺。我們可以通過下載 IPFS 桌面并點擊導(dǎo)入按鈕將我們的 tokenURI 和圖像添加到 IPFS。
然后,我們可以通過點擊要共享的文件旁邊的 3 個點、點擊共享鏈接并復(fù)制給定的鏈接來共享 URI。然后我們可以將此鏈接添加到我們的 set_tokenuri.py 文件中以更改我們想要使用的 tokenURI。
持久性
但是,如果 tokenURI 僅在我們的節(jié)點上,這意味著當(dāng)我們的節(jié)點關(guān)閉時,沒有其他人可以查看它。所以我們希望其他人 pin我們的 NFT。我們可以使用 Pinata 之類的 pin服務(wù)來幫助我們的數(shù)據(jù)保持活動狀態(tài),即使我們的 IPFS 節(jié)點已關(guān)閉。
我想未來會有越來越多的元數(shù)據(jù)存儲在 IPFS 和去中心化存儲平臺上。集中式服務(wù)器可能會宕機,這意味著這些 NFT 上的藝術(shù)將永遠丟失。請務(wù)必檢查您使用的 NFT 的 tokenURI 所在的位置!
我也希望更多的人會使用像 Filecoin 這樣的 dStorage 平臺,因為使用 pin服務(wù)也沒有像它應(yīng)該的那樣去中心化。
現(xiàn)在,您已經(jīng)具備了制作漂亮有趣、可定制、交互式 NFT 的技能,并讓它們在市場上呈現(xiàn)。
NFT 是一種有趣、強大的方式,可以補償藝術(shù)家們所做的辛勤工作。
網(wǎng)站欄目:用Python制作NFT區(qū)塊鏈作品(下)
地址分享:http://www.fisionsoft.com.cn/article/djpgsgo.html


咨詢
建站咨詢
