updated for opensea compatibility

This commit is contained in:
PatrickAlphaC
2020-11-25 00:05:42 -05:00
parent 32d6f9be71
commit 7b8eb6b522
13 changed files with 1998 additions and 2538 deletions

View File

@@ -1,12 +1,13 @@
# Chainlink Random Character Creation
This repo is a starting point for creating:
1. NFTs built with provable RNG using the [Chainlink VRF](https://docs.chain.link/docs/get-a-random-number)
1. NFTs built with verifiable RNG using the [Chainlink VRF](https://docs.chain.link/docs/get-a-random-number)
2. Create dynamic NFTs that change based on real world data. [By using decentralized oracles to get data.](https://docs.chain.link/docs/make-a-http-get-request)
3. Adding your randomized NFTs to the [OpenSea Marketplace](https://opensea.io/)
We will easily create our own NFT on the Rinkeby Chain. We can edit the name of the character in the [`generate-character.js`](./scripts/generate-character.js) script. Right now, the character defaults to "Garfield the Chainlink Warrior".
We will easily create our own NFT on the Rinkeby Chain. We can edit the name of the character in the [`generate-character.js`](./scripts/generate-character.js) script.
This will create a character with 6 attributes from 0 - 18:
This will create a character with 6 attributes from 0 - 99:
- uint256 strength;
- uint256 dexterity;
- uint256 constitution;

File diff suppressed because one or more lines are too long

View File

@@ -1419,8 +1419,8 @@
"4": {
"events": {},
"links": {},
"address": "0x746eD7554253A9C5Ab5A6800F19010B247cb97fC",
"transactionHash": "0xa8ae9bd1b3783cf04b048085b5170af45630f9feaf184685cce10c2f0cd96d14"
"address": "0xc3e7A50d2Bc7755FeE541AFD9377499baE705E21",
"transactionHash": "0x3dfcd6c004ab0de57ce17f791386654c64427c5eca9ece4cb46ecc849a7120a4"
},
"42": {
"events": {},
@@ -1430,7 +1430,7 @@
}
},
"schemaVersion": "3.2.5",
"updatedAt": "2020-11-25T02:10:33.933Z",
"updatedAt": "2020-11-25T02:35:12.044Z",
"networkType": "ethereum",
"devdoc": {
"methods": {}

View File

@@ -41,7 +41,7 @@ contract DungeonsAndDragonsCharacter is ERC721, VRFConsumerBase, Ownable {
*
* Network: Rinkeby
* Chainlink VRF Coordinator address: 0xb3dCcb4Cf7a26f6cf6B120Cf5A73875B7BBc655B
* LINK token address: 0xa36085f69e2889c224210f603d836748e7dc0088
* LINK token address: 0x01BE23585060835E02B77ef475b0Cc51aA1e0709
* Key Hash: 0x2ed0feb3e7fd2022120aa84fab1945545a9f2ffc9076fd6156fa96eaff4c1311
*/
constructor(address _VRFCoordinator, address _LinkToken, bytes32 _keyhash)
@@ -86,13 +86,12 @@ contract DungeonsAndDragonsCharacter is ERC721, VRFConsumerBase, Ownable {
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 strength = (randomNumber % 100);
uint256 dexterity = ((randomNumber % 10000) / 100 );
uint256 constitution = ((randomNumber % 1000000) / 10000 );
uint256 intelligence = ((randomNumber % 100000000) / 1000000 );
uint256 wisdom = ((randomNumber % 10000000000) / 100000000 );
uint256 charisma = ((randomNumber % 1000000000000) / 10000000000);
uint256 experience = 0;
characters.push(

View File

@@ -1,35 +0,0 @@
// SPDX-License-Identifier: MIT
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";
contract RandomNFT is ERC721, VRFConsumerBase, Ownable {
address public VRFCoordinator = 0xb3dCcb4Cf7a26f6cf6B120Cf5A73875B7BBc655B;
address public LinkToken = 0x01BE23585060835E02B77ef475b0Cc51aA1e0709;
uint256 power;
bytes32 internal keyHash;
uint256 internal fee;
constructor() public
VRFConsumerBase(VRFCoordinator, LinkToken)
ERC721("randomNFT", "rNFT"){
power = 0;
keyHash = 0x2ed0feb3e7fd2022120aa84fab1945545a9f2ffc9076fd6156fa96eaff4c1311;
fee = 0.1 * 10**18; // 0.1 LINK
_safeMint(msg.sender, 0);
}
function requestRandomPower(uint256 seed) public{
require(
LINK.balanceOf(address(this)) >= fee,
"Not enough LINK - fill contract with faucet"
);
requestRandomness(keyHash, fee, seed);
}
function fulfillRandomness(bytes32 requestId, uint256 randomness) internal override {
power = randomness % 100;
}
}

35
metadata/elf.json Normal file
View File

@@ -0,0 +1,35 @@
{
"name": "Sergey the Elf",
"description": "Inspiring, Based, Mythical, Oracle loving creature. Leading the new world and helping teach about superior digital agreements. Also is good with a bow!",
"image": "https://ipfs.io/ipfs/QmTgqnhFBMkfT9s8PHKcdXBn1f5bG3Q5hmBaR4U6hoTvb1?filename=Chainlink_Elf.png",
"attributes": [
{
"trait_type": "Strength",
"value": 63
},
{
"trait_type": "Dexterity",
"value": 10
},
{
"trait_type": "Constitution",
"value": 7
},
{
"trait_type": "Intelligence",
"value": 6
},
{
"trait_type": "Wisdom",
"value": 51
},
{
"trait_type": "Charisma",
"value": 80
},
{
"trait_type": "Experience",
"value": 0
}
]
}

35
metadata/knight.json Normal file
View File

@@ -0,0 +1,35 @@
{
"name": "Julian the Knight",
"description": "Defender against Flash Loan attacks, protector of #Defi protocols. Helping keep the smart contract kingdom secure, reliable, and safe. Also is an amazing artist. ",
"image": "https://ipfs.io/ipfs/QmZGQA92ri1jfzSu61JRaNQXYg1bLuM7p8YT83DzFA2KLH?filename=Chainlink_Knight.png",
"attributes": [
{
"trait_type": "Strength",
"value": 67
},
{
"trait_type": "Dexterity",
"value": 94
},
{
"trait_type": "Constitution",
"value": 34
},
{
"trait_type": "Intelligence",
"value": 81
},
{
"trait_type": "Wisdom",
"value": 45
},
{
"trait_type": "Charisma",
"value": 4
},
{
"trait_type": "Experience",
"value": 0
}
]
}

35
metadata/orc.json Normal file
View File

@@ -0,0 +1,35 @@
{
"name": "Pepe the Orc",
"description": "This green tweeting machine is one of the most exciting and excited creatures on the planet. Don't let his looks fool you, he loves to love new technology and help others get involved. Loves watching 'JSON Parser",
"image": "https://ipfs.io/ipfs/QmW1toapYs7M29rzLXTENn3pbvwe8ioikX1PwzACzjfdHP?filename=Chainlink_Orc.png",
"attributes": [
{
"trait_type": "Strength",
"value": 90
},
{
"trait_type": "Dexterity",
"value": 16
},
{
"trait_type": "Constitution",
"value": 76
},
{
"trait_type": "Intelligence",
"value": 54
},
{
"trait_type": "Wisdom",
"value": 85
},
{
"trait_type": "Charisma",
"value": 3
},
{
"trait_type": "Experience",
"value": 0
}
]
}

35
metadata/witch.json Normal file
View File

@@ -0,0 +1,35 @@
{
"name": "Ari the Witch",
"description": "Brilliant spell-slinger and magical with cryptography. Often uses Jewles in his h-index potions. ",
"image": "https://ipfs.io/ipfs/QmPMwQtFpEdKrUjpQJfoTeZS1aVSeuJT6Mof7uV29AcUpF?filename=Chainlink_Witch.png",
"attributes": [
{
"trait_type": "Strength",
"value": 43
},
{
"trait_type": "Dexterity",
"value": 26
},
{
"trait_type": "Constitution",
"value": 61
},
{
"trait_type": "Intelligence",
"value": 74
},
{
"trait_type": "Wisdom",
"value": 48
},
{
"trait_type": "Charisma",
"value": 70
},
{
"trait_type": "Experience",
"value": 0
}
]
}

View File

@@ -1,6 +1,6 @@
const DungeonsAndDragonsCharacter = artifacts.require('DungeonsAndDragonsCharacter')
const RINKEBY_VRF_COORDINATOR = '0xb3dCcb4Cf7a26f6cf6B120Cf5A73875B7BBc655B'
const RINKEBY_LINKTOKEN = '0xa36085f69e2889c224210f603d836748e7dc0088'
const RINKEBY_LINKTOKEN = '0x01be23585060835e02b77ef475b0cc51aa1e0709'
const RINKEBY_KEYHASH = '0x2ed0feb3e7fd2022120aa84fab1945545a9f2ffc9076fd6156fa96eaff4c1311'
module.exports = async (deployer, network, [defaultAccount]) => {

View File

@@ -8,17 +8,17 @@ const LinkTokenInterface = artifacts.require('LinkTokenInterface')
can be retrieved by calling the withdrawLink() function.
*/
const payment = process.env.TRUFFLE_CL_BOX_PAYMENT || '1000000000000000000'
const payment = process.env.TRUFFLE_CL_BOX_PAYMENT || '3000000000000000000'
module.exports = async callback => {
try {
const dnd = await DungeonsAndDragonsCharacter.deployed()
const tokenAddress = await dnd.LinkToken()
console.log("Chainlink Token Address: ", tokenAddress)
const token = await LinkTokenInterface.at(tokenAddress)
console.log('Funding contract:', dnd.address)
const tx = await token.transfer(dnd.address, payment)
console.log(tx)
callback(tx.tx)
} catch (err) {
callback(err)

View File

@@ -2,10 +2,10 @@ const DungeonsAndDragons = artifacts.require('DungeonsAndDragonsCharacter')
module.exports = async callback => {
const dnd = await DungeonsAndDragons.deployed()
console.log('Creating request on contract:', dnd.address)
const tx = await dnd.requestNewRandomCharacter(77, "Julian the Knight")
const tx2 = await dnd.requestNewRandomCharacter(7777777, "Sergey the Elf")
const tx3 = await dnd.requestNewRandomCharacter(7, "Ari the Witch")
const tx4 = await dnd.requestNewRandomCharacter(777, "Pepe the Orc")
console.log('Creating requests on contract:', dnd.address)
// const tx = await dnd.requestNewRandomCharacter(77, "Julian the Knight")
// const tx2 = await dnd.requestNewRandomCharacter(7777777, "Sergey the Elf")
const tx3 = await dnd.requestNewRandomCharacter(7, "Ari the Wizard")
// const tx4 = await dnd.requestNewRandomCharacter(777, "Pepe the Orc")
callback(tx.tx)
}

View File

@@ -3,7 +3,10 @@ const TOKENID = 0
module.exports = async callback => {
const dnd = await DungeonsAndDragons.deployed()
console.log('Let\'s set the tokenURI of your character')
const tx = await dnd.setTokenURI(TOKENID, "ipfs_url_here")
// const tx = await dnd.setTokenURI(0, "https://ipfs.io/ipfs/QmVKfktQ2hLwPEiGaymEajLQGavGGZDSYkwhdo7M17J2z4?filename=knight.json")
const tx = await dnd.setTokenURI(1, "https://ipfs.io/ipfs/QmTzQzKymQcv2BhGuVNmfLGePoD43rhQEM5eSkxsLFTB9c?filename=elf.json")
const tx1 = await dnd.setTokenURI(2, "https://ipfs.io/ipfs/QmREDfvFTT24qC4u7wVXXujtiuP1RfvtHyupwdfGPQDyQi?filename=witch.json")
const tx2 = await dnd.setTokenURI(3, "https://ipfs.io/ipfs/QmS2u1bPTQdAnDYrXE7qzLxyB6sYx2rN6oo8XkYP6sxbd6?filename=orc.json")
console.log(tx)
callback(tx.tx)
}