Assignment - Get Kitty

here is my code and getKitty function

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

import "./IERC721.sol";
import "./SafeMath.sol";
import "./Ownable.sol";

  contract KittyContract is IERC721,  Ownable {

  using SafeMath for uint256;

  mapping(uint256 => address) public kittyIndexToOwner; // an interger or index to an address
  mapping(address => uint256) ownershipTokenCount; // an address to a number, a count
  mapping(address => uint256[]) ownerToCats; //an address to a number of cats in an array

  //mapping(uint256 => address) private _tokenApprovals;

  event Birth(address owner, uint256 kittenId, uint256 mumId, uint256 dadId, uint256 genes);

  // if made 'public constant', getter functions would be created
  // automatically, thus there would be no need to create getter functions
  // it's optional
  uint256 public constant CERATION_LIMIT_GEN0 = 10; // max num of cats to be generated
  uint256 public gen0Counter;
 

  string private _name;
  string private _symbol;

  struct Kitty{
  uint64 birthTime;
  uint32 mumId;
  uint32 dadId;
  uint16 generation;
  uint256 genes;
}

Kitty[] kitties;

  constructor(string memory name_, string memory symbol_) {
    _name = name_;
    _symbol = symbol_;
    owner = msg.sender;
}


  function name() external view override returns (string memory tokenName) {
    return _name;
  }

  function symbol() external view override returns (string memory tokenSymbol) {
    return _symbol;
  }

  // could be external but externals can only be called from outside not within this contract
  function totalSupply() public view override returns (uint256 total) {
    return kitties.length;

  }

  function getAllCatsFor(address owner) external view returns (uint[] memory cats) {
    return  ownerToCats[owner];
  }


  function balanceOf(address owner) external view override returns (uint256 balance ) {
    return ownershipTokenCount[owner];
  }

  function ownerOf(uint256 tokenId) external view override returns (address owner) {
    address _owner = kittyIndexToOwner[tokenId];
    require(_owner != address(0), "ERC721: owner query for nonexistent token");

    return _owner;
  }
  

  function getKitty(uint256 tokenId) public view returns(uint256 birthTime, uint256 mumId, uint256 dadId, uint256 generation, uint256 genes ) {
    Kitty memory returnKitty = kitties[tokenId];
    return (returnKitty.birthTime,  returnKitty.mumId, returnKitty.dadId, returnKitty.generation, returnKitty.genes) ;
  }

  /*

  function approve(address to, uint256 tokenId) public virtual {
    address _owner = kittyIndexToOwner[tokenId];
    require(to != _owner);
    require(msg.sender == _owner);

    _approve(to, tokenId);

  }
  */

   // available function to outside calls - it only sends from msg.sender to recipients
  function transfer(address to, uint256 tokenId) external override {
    require(to != address(this), "to cannot be the contract address" );
    require(to != address(0),"to cannot be the zero address" );
    require(_owns(msg.sender, tokenId));

    _transfer(address(0), to, tokenId);
    
    // might need to input _from instead of msg.sender to transfer from 0 address
    emit Transfer(address(0), to, tokenId);
     
  }

  function createKittyGen0(uint256 _genes) public onlyOwner returns(uint256){
    require(gen0Counter < CERATION_LIMIT_GEN0, "Gen 0 should be less than creation limit gen 0");

    gen0Counter++;

    // mum, dad and generation is 0
    // Gen0 have no owners; they are owned by the contract
   return  _createKitty(0,0,0, _genes, msg.sender); // msg.sender could also be -- address(this) - we are giving cats to owner

  }

  // create cats by generation and by breeding
  // retuns cat id
  function _createKitty(
    //uint256 _catId,
    uint256 _mumId,
    uint256 _dadId,
    uint256 _generation, //1,2,3..etc
    uint256 _genes,
    address owner // recipient
  ) private returns(uint256) {
    Kitty memory newKitties = Kitty({ // create struct object
      //catId: _catId,
      genes: _genes,
      birthTime: uint64(block.timestamp),
      mumId: uint32(_mumId),
      dadId: uint32(_dadId),
      generation: uint16(_generation)
     });

     kitties.push(newKitties); // returns the size of array - 1 for the first cat

     uint256 newKittenId = kitties.length -1; // 0 -1

     emit Birth(owner, newKittenId, _mumId, _dadId, _genes);

     _transfer(address(0), owner, newKittenId); // birth of a cat from 0 (standard)

    return newKittenId; //returns 256 bit integer

  }


 

  // must transfer from address 0
  function _transfer(address from,  address to, uint256 tokenId) internal {
    //_approve(address(0), tokenId);

    ownershipTokenCount[to] = ownershipTokenCount[to].add(1);

    kittyIndexToOwner[tokenId] = to;
    ownerToCats[to].push(tokenId);
   
    // decrease token count from person A to person B
    if (from != address(0)) {
      ownershipTokenCount[from] = ownershipTokenCount[from].sub(1);
        _removeTokenIdFromOwner(from, tokenId);
    }
     
  }

    function _removeTokenIdFromOwner(address owner, uint256 tokenId) internal {
      uint256 lastId = ownerToCats[owner][ownerToCats[owner].length -1];
      for (uint256 i = 0; i < ownerToCats[owner].length; i++) {
        if (ownerToCats[owner][i] == tokenId) {
            ownerToCats[owner][i] = lastId;
            ownerToCats[owner].pop();
        }

      }

  }

/*
  function _approve(address to, uint256 _tokenId) internal virtual {
    address _owner = kittyIndexToOwner[_tokenId];
    _tokenApprovals[_tokenId] = to;
    emit Approval(_owner, to, _tokenId);

  }
  */
  
  function _owns(address _claimant, uint256 tokenId) internal view returns(bool) {
    return kittyIndexToOwner[tokenId] == _claimant;
  }

}
2 Likes

Here is my code for the function:

function createKittyGen0(uint256 _genes) public onlyOwner returns(uint256) {
        _createKitty(0, 0, 0, _genes, msg.sender);
    }

And this is my code for Ownable:

pragma solidity ^0.5.12;

contract Ownable {

    address public owner;

    modifier onlyOwner {
        require (msg.sender == owner, "You are not the owner");
        _;
    }
}
1 Like

This is the solution of the previous exercise. Sorry

Please find my code:

function getKitty (uint256 tokenId) returns (
        uint256 genes, 
        uint256 birthTime
        uint256 mumId, 
        uint256 dadId, 
        uint256 generation){

        return (
            Kitty[tokenId].genes, 
            Kitty[tokenId].birthTime, 
            Kitty[tokenId].mumId, 
            Kitty[tokenId].dadId, 
            Kitty[tokenId].generation
        );
    }
My solution
/// SPDX-License-Identifier: MIT
pragma solidity >=0.4.22 <0.9.0;

import "./IERC721.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

contract Kittycontract is IERC721, Ownable{
    
    uint256 public constant CREATION_LIMIT_GEN0 = 10;
    string constant _tokenName = "CryptoKitties";
    string constant _tokenSymbol = "CK";

    event Birth(
           address owner,
        uint256 kittenId,
        uint256 mumId,
        uint256 dadId,
        uint256 genes);

    struct Kitty{
        uint256 genes;
         uint64 birthTime;
        uint32 mumId;
        uint32 dadId;
        uint16 generation;
    }

    Kitty[] kitties;

    mapping(address => uint256) ownershipTokenCount;
    mapping(uint256 => address) public kittyindexToOwner;

    uint256 public gen0Counter;

    function createKittyGen0(uint256 _genes) public onlyOwner returns (uint256){
        require(gen0Counter < CREATION_LIMIT_GEN0);
        gen0Counter++;
        return _createKitty(0, 0, 0, _genes, msg.sender);
    }

    function _createKitty(
        uint256 _genes,
        uint256 _mumId,
        uint256 _dadId,
        uint256 _generation,
        address _owner
    ) private returns (uint256){
        Kitty memory _kitty = Kitty({
            genes: uint64(_genes),
            birthTime: uint64(block.timestamp),
            mumId: uint32(_mumId),
            dadId: uint32(_dadId),
            generation:  uint16(_generation)
        });
    
        kitties.push(_kitty);
       uint256 newKittenId = kitties.length - 1;

       emit Birth(_owner, newKittenId, _mumId, _dadId, _genes);

       _transfer(address(0), _owner, newKittenId);

       return newKittenId;
    }

    function getKitty(uint256 kittyId) public view returns (uint256, uint64, uint32, uint32, uint16){
        return (
            kitties[kittyId].genes,
            kitties[kittyId].birthTime,
            kitties[kittyId].mumId, 
            kitties[kittyId].dadId,
            kitties[kittyId].generation
            );
    }
        

    function balanceOf(address owner) external override view returns (uint256 balance){
        return ownershipTokenCount[owner];
    }

    function totalSupply() public override view  returns (uint256 total){
        return kitties.length;
    }

     function name() external override pure returns (string memory){return _tokenName;}

    function symbol() external override pure returns (string memory){return _tokenSymbol;}

    function ownerOf(uint256 tokenId) external view override returns (address){
        return kittyindexToOwner[tokenId];
    }

    function transfer(address _to, uint256 _tokenId) external override{
        require(_to != address(0), "Cannot send tokens to this address");
        require(ownershipTokenCount[msg.sender]>0, "Not enough tokens");
        require(kittyindexToOwner[_tokenId]==msg.sender, "You must own the token");
    
        _transfer(msg.sender, _to, _tokenId);
    }

    function _transfer(address _from, address _to, uint256 _tokenId) internal {

        ownershipTokenCount[_to]++;
        kittyindexToOwner[_tokenId] = _to;
        
        if(_from !=address(0)){
        ownershipTokenCount[_from]--;

        }
        emit Transfer(_from, _to, _tokenId);
    }
}

Hi, Iā€™ve built my kitties smart contract on OpenZeppelin contracts and with a recent Solidity version. I hope you like it.

Kitties.sol
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

contract Kitties is ERC721Enumerable, Ownable {
  struct Kitty {
    uint256 genes;
    uint64 birthTime;
    uint32 mumId;
    uint32 dadId;
    uint16 generation;
  }
  Kitty[] private _kitties;

  // Cap of how many generation 0 kitties can be created.
  uint8 public constant GEN0_CAP = 10;
  uint8 private _gen0Counter;

  constructor() ERC721("Kitties", "KITS") {}

  event Birth(
    address indexed owner,
    uint256 indexed kittyId,
    uint256 mumId,
    uint256 dadId,
    uint256 genes
  );

  // Creates a generation 0 kitty.
  function createKittyGen0(uint256 genes) public onlyOwner {
    require(_gen0Counter <= GEN0_CAP);
    _gen0Counter++;
    _createKitty(0, 0, 0, genes, owner());
  }

  // Returns how many generation 0 kitties have already been created.
  function countKittiesGen0() public view returns (uint256) {
    return uint256(_gen0Counter);
  }

  // Returns 'kittyId' kitty data.
  function getKitty(uint256 kittyId)
    public
    view
    returns (
      uint256 genes,
      uint256 birthTime,
      uint256 mumId,
      uint256 dadId,
      uint256 generation
    )
  {
    require(_exists(kittyId), "Nonexistent");
    Kitty storage kitty = _kitties[kittyId];

    genes = kitty.genes;
    birthTime = kitty.birthTime;
    mumId = kitty.mumId;
    dadId = kitty.dadId;
    generation = kitty.generation;
  }

  // ----- NONPUBLIC FUNCTIONS -----

  function _createKitty(
    uint256 mumId,
    uint256 dadId,
    uint256 generation,
    uint256 genes,
    address owner
  ) internal {
    Kitty memory newKitty = Kitty({
      genes: genes,
      birthTime: uint64(block.timestamp),
      mumId: uint32(mumId),
      dadId: uint32(dadId),
      generation: uint16(generation)
    });
    _kitties.push(newKitty);

    uint256 newKittyId = _kitties.length - 1;
    require(newKittyId == uint256(uint32(newKittyId)));
    emit Birth(
      owner,
      newKittyId,
      uint256(newKitty.mumId),
      uint256(newKitty.dadId),
      newKitty.genes
    );

    _safeMint(owner, newKittyId);
  }
}

can we just return the struct ?

like thisā€¦

   function getKiddy(uint256 _tokenId) external view returns (Kitty memory) {
        
        require(_tokenId < kitties.length);
        return kitties[_tokenId];
    }

seems cleaner this way.

pls i need serious help from the place of ferig up my python server down to the place nowā€¦i have gotten so much know how of how to make the code so not having much problem with the code though still having some errors but my major problem is getting my environments set upā€¦pls i will appreciate if anyone can get on zoom with me to show and help me out ā€¦i have been stucked here for daysā€¦btw below is my code:

// SPDX-License-Identifier: MIT
pragma solidity 0.8.0;

import "./IERC721.sol";
import "./node_modules/@openzeppelin/contracts/access/Ownable.sol";

//import "./node_modules/@openzeppelin/contracts/access/Ownable.sol";

contract KittyContract is IERC721, Ownable  {
   
    string public constant name = "TestKitties";
    string public constant symbol = "TK";
    uint256 public constant Creation_Max_Gene0 =10;
  
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
    
   // event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
    
    event Birth (uint256 genes, uint32 mumId, uint32 dadId,  uint256 newKittenId, address _owner);
  
    struct Kitty {
        uint256 genes;
        uint64 birthTime;
        uint32 mumId;
        uint32 dadId;
        uint16 generation;
    }
      
        Kitty[] kitties;

    mapping (uint256 => address) public kittyIndexToOwner;
    mapping(address => uint256) OwnershipToken;
    mapping (address => uint256[]) ownerToCats;
    
    uint256 public gene0counter;


    function createKittyGene0(uint256 _genes) public onlyOwner returns(uint256) {
        require(gene0counter <= Creation_Max_Gene0);
        
         gene0counter++;
         
         //gene0 has no owner, it is only owned by the contract
         return  _createKitty(0, 0, 0, 0, _genes, msg.sender);
    }
    
    function getKitty(uint256 tokenId) public view returns(uint256 genes, uint64 birthTime, uint32 mumId, uint32 dadId, uint16 generation) {
         return (
                kitties[_tokenId].genes, 
                kitties[_tokenId].birthTime, 
                kitties[_tokenId].mumId, 
                kitties[_tokenId].dadId, 
                kitties[_tokenId].generation
                );
    }
    function _createKitty(uint256 _genes, uint64 _birthTime, uint32 _mumId,  uint32 _dadId, uint16 _generation, address _owner) internal returns(uint256) {
       Kitty memory _kitty = Kitty({
            genes: uint256(_genes),
            birthTime: uint64(now),
            mumId: uint32(_mumId),
            dadId: uint32(_dadId),
            generation: uint16(_generation) 
              });

             kitties.push(_kitty);
             uint256 newKittenId = kitties.length - 1;

        // uint256 newKittenId = kitties.push(_kitty) -1;
         
         emit Birth (_genes, _mumId, _dadId, newKittenId, _owner);

          _transfer(address(0), _owner, newKittenId);

          return newKittenId;
     }
    
     
     
    function balanceOf(address owner) external view returns (uint256 balance) {
          return OwnershipToken[owner];
      } 

    function totalSupply() external  view returns (uint256 total) {
            return kitties.length;
     }
        
    function name() public view returns (string memory tokenName) {
             tokenName = name;
             return tokenName;
    }
        
    function symbol() public view returns (string memory tokenSymbol) {
             tokenSymbol = symbol;
              return tokenSymbol;
    } 
    
       
    function ownerOf(uint256 tokenId) external  view returns (address owner) {
     
               return kittyIndexToOwner[tokenId];
     }
             
    function transfer(address _to, uint256 _tokenId) external
    {    
             require(_to != address(0)); 

             require(_to != address(this));
             require(_owns(msg.sender, _tokenId));

             _transfer(msg.sender, _to, _tokenId);
    }
          
    function _transfer(address _from, address _to, uint256 _tokenId) internal {
            OwnershipToken[_to]++;

           kittyIndexToOwner[_tokenId] = _to;
            ownerToCats[_to].push(_tokenId);

           if (_from != address(0)) {
            OwnershipToken[_from]--;
          //  _removeTokenIdFromOwner(_from, _tokenId);
  }

        // Emit the transfer event.
            emit Transfer(_from, _to, _tokenId);
    }
    function _owns(address _claimant, uint256 _tokenId) internal view returns(bool) {
        return kittyIndexToOwner[_tokenId] == _claimant;
    }
        
}

Hey @Phaxsam so the issue is to run the Server?
I you use visual code studio you can download a plugin called LiveServer is one click server.
Also you can look for programs like wampServer or MampServer. But easies is or plugin or running server from command line.

Here is my code:

assignment getKitty()
function getKitty(uint256 _tokenId) external view returns (
        uint256 genes,
        uint64 birthTime,
        uint32 mumId,
        uint32 dadId,
        uint16 generation
    ) {
        return (
            kitties[_tokenId].genes,
            kitties[_tokenId].birthTime,
            kitties[_tokenId].mumId,
            kitties[_tokenId].dadId,
            kitties[_tokenId].generation
        );
    }
1 Like

Assignment :

struct Kitty{
       uint256 genes;
       uint64 birthTime;
       uint32 mumId;
       uint32 dadId;
       uint16 generation;
   }
   Kitty[] kitties;

   mapping(address => uint)private ownershipTokenCount; //token owner => #tokens
   mapping(uint => address)private tokenOwner; // tokenId => tokenowner
   mapping(address => uint[])ownershipTokenList; // tokenOwner => list of tokenIds
   uint gen0Counter;
   

   function getKitty(uint _tokenId) public view returns(Kitty memory,address){
      return (kitties[_tokenId],tokenOwner[_tokenId]);
   }

hey,
Iā€™m facing an issue: when I run the below command, it goes in like foreverā€¦it simply gets stuck after the Deploying ā€˜Migrationsā€™ line. To deal with this, every time Iā€™m just switching to a new terminal window. Iā€™m sure there must be a better solution.
Can anybody help me in resolving this one?

truffle(ganache)> migrate 

Compiling your contracts...
===========================
> Everything is up to date, there is nothing to compile.



Starting migrations...
======================
> Network name:    'ganache'
> Network id:      5777
> Block gas limit: 6721975 (0x6691b7)


1_initial_migration.js
======================

   Deploying 'Migrations'
   ----------------------

hey @tanu_g the command you need to run is truffle migrate --reset
Please also check your truffle config file. You can send me a photo to check it out.

If you are using visual code studio, you can use the console inside of it.

1 Like

Thanks, @kenn.eth.
hereā€™s the truffle-config.js

/**
 * Use this file to configure your truffle project. It's seeded with some
 * common settings for different networks and features like migrations,
 * compilation and testing. Uncomment the ones you need or modify
 * them to suit your project as necessary.
 *
 * More information about configuration can be found at:
 *
 * trufflesuite.com/docs/advanced/configuration
 *
 * To deploy via Infura you'll need a wallet provider (like @truffle/hdwallet-provider)
 * to sign your transactions before they're sent to a remote public node. Infura accounts
 * are available for free at: infura.io/register.
 *
 * You'll also need a mnemonic - the twelve word phrase the wallet uses to generate
 * public/private key pairs. If you're publishing your code to GitHub make sure you load this
 * phrase from a file you've .gitignored so it doesn't accidentally become public.
 *
 */

const HDWalletProvider = require('@truffle/hdwallet-provider');
const fs = require('fs');
//const mnemonic = fs.readFileSync(".secret").toString().trim();
const mnemonicDev = "vocal mixed asset slim abandon auction joke shoot world door kiss anxiety";

module.exports = {
  /**
   * Networks define how you connect to your ethereum client and let you set the
   * defaults web3 uses to send transactions. If you don't specify one truffle
   * will spin up a development blockchain for you on port 9545 when you
   * run `develop` or `test`. You can ask a truffle command to use a specific
   * network from the command line, e.g
   *
   * $ truffle test --network <network-name>
   */

  networks: {
    // Useful for testing. The `development` name is special - truffle uses it by default
    // if it's defined here and no other network is specified at the command line.
    // You should run a client (like ganache-cli, geth or parity) in a separate terminal
    // tab if you use this network and you must also set the `host`, `port` and `network_id`
    // options below to some value.
    //
    // development: {
    //  host: "127.0.0.1",     // Localhost (default: none)
    //  port: 7545,            // Standard Ethereum port (default: none)
    //  network_id: "*",       // Any network (default: none)
    // },
  ganache: {
     provider: () => new HDWalletProvider(mnemonicDev, `HTTP://127.0.0.1:7545`),
     host: "127.0.0.1",     // Localhost (default: none)
     network_id: "*"       // Any network (default: none)
    },

    // Another network with more advanced options...
    // advanced: {
    // port: 8777,             // Custom port
    // network_id: 1342,       // Custom network
    // gas: 8500000,           // Gas sent with each transaction (default: ~6700000)
    // gasPrice: 20000000000,  // 20 gwei (in wei) (default: 100 gwei)
    // from: <address>,        // Account to send txs from (default: accounts[0])
    // websocket: true        // Enable EventEmitter interface for web3 (default: false)
    // },
    // Useful for deploying to a public network.
    // NB: It's important to wrap the provider as a function.
    // ropsten: {
    // provider: () => new HDWalletProvider(mnemonic, `https://ropsten.infura.io/v3/YOUR-PROJECT-ID`),
    // network_id: 3,       // Ropsten's id
    // gas: 5500000,        // Ropsten has a lower block limit than mainnet
    // confirmations: 2,    // # of confs to wait between deployments. (default: 0)
    // timeoutBlocks: 200,  // # of blocks before a deployment times out  (minimum/default: 50)
    // skipDryRun: true     // Skip dry run before migrations? (default: false for public nets )
    // },
    // Useful for private networks
    // private: {
    // provider: () => new HDWalletProvider(mnemonic, `https://network.io`),
    // network_id: 2111,   // This network is yours, in the cloud.
    // production: true    // Treats this network as if it was a public net. (default: false)
    // }
  },

  // Set default mocha options here, use special reporters etc.
  mocha: {
    // timeout: 100000
  },

  // Configure your compilers
  compilers: {
    solc: {
      version: "0.8.0",    // Fetch exact version from solc-bin (default: truffle's version)
      // docker: true,        // Use "0.5.1" you've installed locally with docker (default: false)
      // settings: {          // See the solidity docs for advice about optimization and evmVersion
      //  optimizer: {
      //    enabled: false,
      //    runs: 200
      //  },
      //  evmVersion: "byzantium"
      // }
    }
  },

  // Truffle DB is currently disabled by default; to enable it, change enabled: false to enabled: true
  //
  // Note: if you migrated your contracts prior to enabling this field in your Truffle project and want
  // those previously migrated contracts available in the .db directory, you will need to run the following:
  // $ truffle migrate --reset --compile-all

  db: {
    enabled: false
  }
};

hey @kenn.eth,
Still facing the same problem with the below command, feels like it is taking ages to deploy.

truffle(ganache)> truffle migrate --reset

Compiling your contracts...
===========================
> Everything is up to date, there is nothing to compile.



Starting migrations...
======================
> Network name:    'ganache'
> Network id:      5777
> Block gas limit: 6721975 (0x6691b7)


1_initial_migration.js
======================

   Deploying 'Migrations'
   ----------------------

You gotta do it in the project folder. Dont use truffle console

1 Like

yeahā€¦thanks Kenneth

getKitty function

function getKitty (uint256 tokenId) external view returns (uint256 genes, uint64 birthTime, uint32 mumId, uint32 dadId, uint16 generation) {
    genes = kitties[tokenId].genes;
    birthTime = kitties[tokenId].birthTime;
    mumId = kitties[tokenId].mumId;
    dadId = kitties[tokenId].dadId;
    generation = kitties[tokenId].generation;
}
1 Like

kittycontract.sol

pragma solidity 0.8.1;

import "./IERC721.sol";

contract Kittycontract is IERC721{

    address contractOwner;
    uint256 CREATION_LIMIT_GEN0 = 10;

    constructor(){
        contractOwner = msg.sender;
    }

    modifier onlyOwner{
        require(contractOwner == msg.sender);
        _;
    }

    event Birth(address owner, uint256 kittenId, uint256 mumId, uint256 dadId, uint256 genes);

    struct Kitty {
        uint genes;
        uint64 birthTime;
        uint32 mumId;
        uint32 dadId;
        uint16 generation;
    }

    Kitty[] kitties;

    mapping(address => uint256) ownershipTokenCount;
    mapping(uint => address) tokenIdOwners;
    mapping(uint => bool) tokenExists;

    uint256 gen0counter;

    function createKittyGen0(uint256 _genes) public onlyOwner returns(uint256) {
        require(gen0counter < CREATION_LIMIT_GEN0);

        gen0counter++;

        return _createKitty(0, 0, 0, _genes, msg.sender);
    }

    function _createKitty(
        uint256 _mumId,
        uint256 _dadId,
        uint256 _generation,
        uint256 _genes,
        address _owner
    ) private returns (uint256) {
        Kitty memory _kitty = Kitty({
            genes: _genes,
            birthTime: uint64(block.timestamp),
            mumId: uint32(_mumId),
            dadId: uint32(_dadId),
            generation: uint16(_generation)
        });

        kitties.push(_kitty);
        uint256 newKittenId = kitties.length - 1;

        emit Birth(_owner, newKittenId, _mumId, _dadId, _genes);

        _transfer(address(0), _owner, newKittenId);

        return newKittenId;
    }

    function getKitty(uint _id) public view returns(Kitty memory){
        return kitties[_id];
    }

    function balanceOf(address _owner) external view override returns (uint256 balance){
        return ownershipTokenCount[_owner];
    }

    function totalSupply() external view override returns (uint256 total){
        return kitties.length;
    }

    function name() external override pure returns (string memory tokenName){
        return "Maxs Kitties";
    }

    function symbol() external override pure returns (string memory tokenSymbol){
        return "MXK";
    }

    function ownerOf(uint256 tokenId) external view override returns (address owner){
        require(tokenExists[tokenId] == true, "Token does not exist");
        return tokenIdOwners[tokenId];
    }

    function transfer(address _to, uint256 _tokenId) external override{
        require(tokenExists[_tokenId] == true, "Token does not exist");
        require(_to != address(0), "You can't transfer to address 0");
        require(_to != address(this), "You can't transfer to this contract");
        require(msg.sender == tokenIdOwners[_tokenId], "You can't transfer tokens you don't own");

        _transfer(msg.sender, _to, _tokenId);
    }

    function _transfer(address _from, address _to, uint256 _tokenId) internal {
        ownershipTokenCount[_to]++;
        tokenIdOwners[_tokenId] = _to;

        if (_from != address(0)) {
            ownershipTokenCount[_from]--;
        }

        emit Transfer(_from, _to, _tokenId);
    }
}
1 Like

Big fail in compiling :frowning_face:

pragma solidity 0.5.0;

import"./IERC271.sol";
import"./Ownable.sol";
import "./node_modules/@openzeppelin/contracts/utils/math/SafeMath.sol";


contract kittycontract is IERC721{
    using SafeMath for uint256;

    uint256 public constant CREATION_LIMIT_GEN0 = 10;
    string public constant Name = "CreepyKitty";
    string public constant Symbol = "CRPY";

    event Birth(
        address owner,
        uint256 kittenId,
        uint256 mumId,
        uint256 dadId,
        uint256 genes
    )

    struct kitty{
        uint256 genes;
        uint64 birthtime;
        uint32 mumId;
        uint32 dadId;
        uint16 generation;
    }

    Kitty[] creepykitty;

    mapping(address => uint256) public kittyIndexToOwner;
    mapping(address => uint256) ownershipToken Count;

    uint256 public gen0counter;



    function createKittyGen0(uint256 _genes) public onlyOwner returns (uint256) {
        require (gen0counter < CREATION_LIMIT_GEN0);

        gen0Counter++;

        //Gen0 have no owners they are own by the contract
        return _createKitty(0,0,0, _genes, msg.sender);
    }

    function _createKitty(
        uint256 _mumId,
        uint256 _dadId,
        uint256 _generation,
        uint256 _genes,
        address _owner
    ) private returns (uint256) {
        kitty memory _kitty = kitty({
            genes: _genes,
            birthTime: uint64(now),
            mumId: uint32(_mumId),
            dadId: uint32(_dadId),
            generation: uint16(_generation)
        });

        uint256 newKittenId = kitty.push(_kitty) - 1;

        emit Birth(_owner, _newKittenId, _mumId, _dadId, _genes);

        _transfer(address(0)), _owner, newKittenId)
             return newKittenId

    }

       
    
    function balanceOf(address owner) external view returns (uint256 balance);
        return ownershipTokenCount [owner];

    
    function totalSupply() public view returns (uint) {
        return creepykitty.length;   
    }
         
    function ownerOf(uint256 tokenId) external view returns (address)
    {
        require(_to != address(0));
        require(_to != address(this));
        require(_owns(msg.sender, _to, _tokenId));

        _transfer(msg.sender, _to, _tokenId);
    }

    function _transfer(address _from, address _to, uint256 _tokenId) internal {
        ownershipTokenCount[_to]++;

        kittyIndexToOwner[_tokenId] = _to;

        if (_from != address(0)) {
            ownershipTokenCount[_from]--;
        }
        emit transfer(_from,_to, _tokenId);
    }
    function _owns(address_claimant, uint256 _tokenId) internal view returns (bool) {
        return kittyIndexToOwner[_tokenId] == _claimant;
    }
  
}

Shot 0016