smartcontractkit / full-blockchain-solidity-course-py

Ultimate Solidity, Blockchain, and Smart Contract - Beginner to Expert Full Course | Python Edition
MIT License
10.76k stars 2.9k forks source link

Breed always the same for advanced NFT #731

Open izamzam2020 opened 2 years ago

izamzam2020 commented 2 years ago

Hi,

Thanks in advance for any help.

I'm working through the advanced NFT section and everything is working apart from a random breed, the breed is always 1.

To be sure I've copied the codebase from Github in case I made any mistakes but the same issue happens.

The contract address is 0xfB372045283C46E134042794c37A87FfA3e48B73 https://rinkeby.etherscan.io/address/0xfB372045283C46E134042794c37A87FfA3e48B73#readContract

If you go into Contract > Read and use the tokenIdToBreed function you will see token 0,1,2,3,4 are all of the breed 1

Here is the code im using for AdvancedCollectible

`// An NFT Contract
// Where the tokenURI can be one of 3 different dogs
// Randomly selected

// SPDX-License-Identifier: MIT
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;
bytes32 public keyhash;
uint256 public fee;
enum Breed{PUG, SHIBA_INU, ST_BERNARD}
mapping(uint256 => Breed) public tokenIdToBreed;
mapping(bytes32 => address) public requestIdToSender;
event requestedCollectible(bytes32 indexed requestId, address requester);
event breedAssigned(uint256 indexed tokenId, Breed breed);

`constructor(address _vrfCoordinator, address _linkToken, bytes32 _keyhash, uint256 _fee) public
VRFConsumerBase(_vrfCoordinator, _linkToken)
ERC721("Dogie", "DOG")
{
    tokenCounter = 0;
    keyhash = _keyhash;
    fee = _fee;
}

function createCollectible() public returns (bytes32){
    bytes32 requestId = requestRandomness(keyhash, fee);
    requestIdToSender[requestId] = msg.sender;
    emit requestedCollectible(requestId, msg.sender);
}

function fulfillRandomness(bytes32 requestId, uint256 randomNumber) internal override {
    Breed breed = Breed(randomNumber % 3);
    uint256 newTokenId = tokenCounter;
    tokenIdToBreed[newTokenId] = breed;
    emit breedAssigned(newTokenId, breed);
    address owner = requestIdToSender[requestId];
    _safeMint(owner, newTokenId);
    tokenCounter = tokenCounter + 1;
}

function setTokenURI(uint256 tokenId, string memory _tokenURI) public {
    // pug, shiba inu, st bernard
    require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not owner no approved");
    _setTokenURI(tokenId, _tokenURI);
}`

Thanks Ian

cromewar commented 2 years ago

Which network are you using to test this? the fullfil randomness is a asynchronous function so it could take some time to actually return the value.