Assignment ERC721

Does anybody know the reason of this problem ? :tired_face:

errorcode

error1

Are you certain that you have implemented all of the functions within the interface IERC721.sol to your Kittycontract ? That solved the issue for me.

1 Like

Why you have 2 safeTransferFrom functions, both are the same, the console is showing an issue with visibility levels, maybe testing with internal instead of external could do the trick, still try to understand the difference between each :nerd_face:

Carlos Z

try to add await at the start of the command, when you create a new cat with instance.createKitty()

Carlos Z

You are right, that caused the error indeed. Thanks a lot Tolga!

2 Likes

Is there a tutorial about how to install and use ganache? I can not find it.

pragma solidity ^0.5.12;
import "./IERC721.sol";
import "./Ownable.sol";

contract KittyContract is Ownable, IERC721 {
    
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
    
    uint256 totalNumberOfTokens;
    string tokenName = "hkKitty";
    string tokenSymbol = "hkK";
    
    struct Kitty {
        string name;
        string ticker;
        uint256 id;
    }

    mapping(address => Kitty[]) ownerKitties;
    mapping(uint256 => address) ownerOfKitty;

    function balanceOf(address owner) external view returns (uint256 balance) {
        return ownerKitties[owner].length;
    }

    function totalSupply() external view returns (uint256 total){
        return totalNumberOfTokens;
    }

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

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

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

    function transfer(address to, uint256 tokenId) external {
        require(to != address(0));
        require(to != address(this));
        require(ownerOfKitty[tokenId] == msg.sender);

        address from = ownerOfKitty[tokenId];
        ownerOfKitty[tokenId] = to;
        emit Transfer(from,to,tokenId);
    }
}
pragma solidity ^0.5.12;

contract Ownable {
    address owner;
    modifier onlyOwner(){
      require(msg.sender == owner);
      _; //Continue execution
  }

    constructor() public {
        owner = msg.sender;
    }
}
1 Like
function getKitty(uint256 kittyId) public returns(uint256, uint64, uint32, uint32, uint16) {
        Kitty kitty = _getKitty(kittyId);
        return(kitty.genes, kitty.birthTime, kitty.mumId, kitty.dadId, kitty.generation);
    }

    function _getKitty(uint256 kittyId) private returns(Kitty) {
        require(kittyId < kitties[length]);
        return kitties[kittyId];
    }

Heavily based on the original crypto kitties contract (and the reading of others answeres ā€¦ :smiley:) here is my solution.

kittyContract.sol.
// SPDX-License-Identifier: MIT
pragma solidity >=0.4.22 <0.9.0;

import "./IERC721.sol";

contract Kittycontract is IERC721{
    string constant _tokenName = "CryptoKitties";
    string constant _tokenSymbol = "CK";

    struct Kitty{
        uint256 genes;
        uint birthTime;
        uint mumId;
        uint dadId;
        uint generation;
    }

    Kitty[] kitties;

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

    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 pure override returns (string memory){
        return _tokenName;
    }

    function symbol() external pure override 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]== to, "Cannot send tokens to sender address");

        ownershipTokenCount[to]++;
        ownershipTokenCount[msg.sender]--;
        kittyindexToOwner[tokenId] = to;
    }

}
1 Like

Here is my Code:

pragma solidity ^0.5.12;

import "./IERC721.sol";

contract Kittycontract is IERC721{

 struct kitty{

 }

    kitty[] kitties;
 mapping( address => uint256) ownershipTokenCount;
 mapping( uint256 => address) ownershipOfToken;

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

    function totalSupply() external view returns (uint256 total){
        return kitties.legth;
    }
    
    function name() external view returns (string memory tokenName){
       return "MyKitties";
    }

    function symbol() external view returns (string memory tokenSymbol){
        return "MKT";
    }

    
    function ownerOf(uint256 tokenId) external view returns (address owner){
        require ( tokenId != 0 );
        return ownershipOfToken[tokenId];
    }

    function transfer(address to, uint256 tokenId) external{
        require (to != address(0), "cannot be your own address");
        require (to != address(this), "cannot be the contract address");
        require ( ownershipOfToken[tokenId] == msg.sender, "You don't own the contract");
        
        _transfer (msg.sender, to, tokenId);

    }

    function _transfer (address from ,address to, uint256 tokenId) internal{
        ownershipTokenCount[to] += tokenId;
        ownershipOfToken[tokenId] = to;
        ownershipTokenCount[from] -= tokenId;
        emit Transfer(from, to, tokenId);
    }
}
1 Like

all setā€¦compilation successfulā€¦

pragma solidity ^0.8.0;

import "./IERC721.sol";

contract Kittycontract is IERC721 {

    uint256 private _totalSupply;

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

    constructor(string memory name_, string memory symbol_) {

        name_ = "Fluffy";
        symbol_ = "FLF";
        _name = name_;
        _symbol = symbol_;
        }

    mapping (uint256 => address) public kittyIndexToOwner; // tokenId => kitty owner
    mapping (address => uint) ownershipTokenCount; //count of how many kitties each owner has
    
    // A mapping from KittyIDs to an address that has been approved to call
    //  transferFrom(). Each Kitty can only have one approved address for transfer
    //  at any time. A zero value means no approval is outstanding.
    mapping (uint256 => address) kittyIndexToApproved;

     //Returns the number of tokens in ``owner``'s account.
    function balanceOf(address owner) external view override returns (uint256) {
        return ownershipTokenCount[owner];
    }

    /*
     * @dev Returns the total number of tokens in circulation.
     */
    function totalSupply() external view override returns (uint256){
        return _totalSupply;
    }
    /*
     * @dev Returns the name of the token.
     */
    function name() external view override returns (string memory){
        return _name;
    }
    /*
     * @dev Returns the symbol of the token.
     */
    function symbol() external view override returns (string memory) {
        return _symbol;
    }
    /**
     * @dev Returns the owner of the `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function ownerOf(uint256 tokenId) external view override returns (address){
        require(kittyIndexToOwner[tokenId] != address(0));
        return kittyIndexToOwner[tokenId];
    }


     /* @dev Transfers `tokenId` token from `msg.sender` to `to`.
     *
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `to` can not be the contract address.
     * - `tokenId` token must be owned by `msg.sender`.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, uint256 tokenId) external override {

        //check that 'to' address is not contract address or zero address
        require(to != address(0) && to != address(this));

        //requiring tokenId is owned by msg.sender
        require(kittyIndexToOwner[tokenId] == msg.sender);

        //updating counts
        ownershipTokenCount[msg.sender]--;
        ownershipTokenCount[to]++;

        //making transfer to 'to'
        kittyIndexToOwner[tokenId] = to;

        //emit event
        emit Transfer(msg.sender,to,tokenId);
    }

 }   

Here is my code:

assignment ERC721 Kittycontract.sol
pragma solidity ^0.5.12;

import "./IERC721.sol";

contract Kittycontract is IERC721 {
    
    string public constant _name = "SerbaKitties"; //Token name
    string public constant _symbol = "SK"; //Token symbol
    
    /**
    * Struct
    */ 
    struct Kitty {
        uint256 genes;
        uint64 birthTime;
        uint32 mumId;
        uint32 dadId;
        uint16 generation;
    }

    Kitty[] kitties; // array of all kitties (index of tokenId)
    
    /**
    * Mappings
    */
    // mapping tokenId to owner address
    mapping(uint256 => address) public kittyIndexToOwner;

    // mapping owner address to tokens owned
    mapping(address => uint256) ownershipTokenCount;

    /**
    * Functions - External
    */
    
    function balanceOf(address owner) external view returns (uint256 balance) {
        return ownershipTokenCount[owner];
    }

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

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

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

    function ownerOf(uint256 _tokenId) external view returns (address owner) {
        return kittyIndexToOwner[_tokenId];
    }

    function transfer(address _to, uint256 _tokenId) external {
        require(_to != address(0), "You CANNOT transfer tokens to address(0)!"); // `to` cannot be to the zero address
        require(_to != address(this), "You CANNOT transfer tokens to this address!"); // `to` cannot be to the contract address
        require(_owns(msg.sender, _tokenId), "You do NOT own this token."); // `tokenId` token must be owned by `msg.sender`
        
        _transfer(msg.sender, _to, _tokenId);

    }

    /**
    *  Functions - Internal
    */ 

    function _transfer(address _from, address _to, uint256 _tokenId) internal {
        //updates the token balance
        ownershipTokenCount[_to]++; 

        kittyIndexToOwner[_tokenId] = _to;

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

        // Emits the transfer event.
        emit Transfer(_from, _to, _tokenId); 
    }

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

}```
1 Like

heya!
This is my code for the basic kitty contract. Here Iā€™m using an additional mapping for storing a list of tokenIds corresponding to the token owner.

kittyContract.sol

// SPDX-License-Identifier: UNLICENSED
pragma solidity >0.4.22 <=0.9.0;
import './IERC721.sol';

contract KittyContract is IERC721{
   uint private _totalSupply;
   string private _name;
   string private _symbol;

   constructor(){
      _name = "Crypto Kitty";
      _symbol = "CKT";
      _totalSupply = 100;
   }

   struct Kitty{
       address tokenOwner;
       uint tokenId;
       uint motherId;
       uint fatherId;
       uint generation;
       uint birthTime;
   }
   Kitty[] kitties;

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

   function balanceOf(address owner) external view override returns (uint256 balance){
       balance = ownershipTokenCount[owner];
   }
   
   function totalSupply() external view override returns (uint256 total){
      total = _totalSupply;
   }

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

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

   function ownerOf(uint256 tokenId) external view override returns (address owner){
      require(tokenOwner[tokenId] != address(0),"Token with this ID doesn't exist");
      owner = tokenOwner[tokenId];
   }
   
   function transfer(address to, uint256 tokenId) external override{
      require(to != address(0),"Receiver can not be zero address");
      require(to != address(this),"You can't transfer token to this contract");
      require(tokenOwner[tokenId] == msg.sender,"You're not the owner of this token");
      _transfer(msg.sender, to, tokenId);
   }

   function _transfer(address from, address to, uint tokenId) internal{
       //from
       if(from != address(0)){
        ownershipTokenCount[from] -= 1;
        uint[] storage fromTokens = ownershipTokenList[from];
        uint len = fromTokens.length;
        uint tokenToRemove = 0;
        for(uint i = 0 ; i < len ; i++){
            if(fromTokens[i] == tokenId){
                tokenToRemove = i;
                break;
            }
        }
        fromTokens[tokenToRemove] = fromTokens[len-1];
        fromTokens.pop();
       }
       
       //to
       ownershipTokenCount[to] += 1;
       tokenOwner[tokenId] = to;
       ownershipTokenList[to].push(tokenId);

       emit Transfer(from,to,tokenId);
   }
}

KittyConract.sol

pragma solidity >=0.4.22 <0.9.0;

import "./IERC721.sol";

abstract contract Kittycontract is IERC721 {

    uint256 private _totalSupply;

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

    constructor(string memory name_, string memory symbol_) {

        name_ = "Gigi";
        symbol_ = "GG";
        _name = name_;
        _symbol = symbol_;
        }

    mapping (uint256 => address) public kittyIndexToOwner; // tokenId => kitty owner
    mapping (address => uint) ownershipTokenCount; //count of how many kitties each owner has
    mapping (uint256 => address) kittyIndexToApproved;

     //Returns the number of tokens in ``owner``'s account.
    function balanceOf(address owner) external view override returns (uint256) {
        return ownershipTokenCount[owner];
    }

    /*
     * @dev Returns the total number of tokens in circulation.
     */
    function totalSupply() external view override returns (uint256){
        return _totalSupply;
    }
    /*
     * @dev Returns the name of the token.
     */
    function name() external view override returns (string memory){
        return _name;
    }
    /*
     * @dev Returns the symbol of the token.
     */
    function symbol() external view override returns (string memory) {
        return _symbol;
    }
    /**
     * @dev Returns the owner of the `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function ownerOf(uint256 tokenId) external view override returns (address){
        require(kittyIndexToOwner[tokenId] != address(0));
        return kittyIndexToOwner[tokenId];
    }

    function transfer(address to, uint256 tokenId) external override {

        //check that 'to' address is not contract address or zero address
        require(to != address(0) && to != address(this));

        //requiring tokenId is owned by msg.sender
        require(kittyIndexToOwner[tokenId] == msg.sender);

        //updating counts
        ownershipTokenCount[msg.sender]--;
        ownershipTokenCount[to]++;

        //making transfer to 'to'
        kittyIndexToOwner[tokenId] = to;

        //emit event
        emit Transfer(msg.sender,to,tokenId);
    }

 }   

3 Likes

Looking for a bit of help here, I have the contract part finished but for some reason the _owns is an undeclared identifier. Not sure where or how to go about declaring it. when I remove it then I get all my functions as errorsā€¦ so Iā€™m a bit confused with the inheritance of this project and its functionsā€¦ I feel like itā€™s something dumb Iā€™m missing but cant seems to get it haha Any ideas? @thecil

pragma solidity >=0.4.22 <0.9.0;

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

 contract Kittycontract is IERC721, Ownable {
    
    // Gen 0 Creation Limit
    uint256 public constant CREATION_LIMIT_GEN0 = 10;

    // Token name
    string public constant name = "MickeyKitties";

    // Token symbol
    string public constant symbol = "GG";

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


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

    Kitty[] kitties;

    mapping (uint256 => address) public kittyIndexToOwner; // tokenId => kitty owner
    mapping (address => uint) ownershipTokenCount; //count of how many kitties each owner has

    uint256 public gen0Counter;


    function getKitty(uint256 _id) external view returns (
        uint256 genes,
        uint256 birthTime,
        uint256 momId,
        uint256 dadId,
        uint256 generation
    )
    {
        Kitty storage kitty = kitties[_id];

        birthTime = uint256(kitty.birthTime);
        momId = uint256(kitty.momId);
        dadId = uint256(kitty.dadId);
        generation = uint256(kitty.generation);
        genes = kitty.genes;
    }
    
    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 _momId,
        uint256 _dadId,
        uint256 _generation,
        uint256 _genes,
        address _owner
    )  private returns (uint256) {
        Kitty memory _kitty = Kitty({
            genes: _genes,
            birthTime: uint64(now),
            momId: uint32(_momId),
            dadId: uint32(_dadId),
            generation: uint16(_generation)
        });

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

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

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

        return newKittenId;
    }

     //Returns the number of tokens in ``owner``'s account.
    function balanceOf(address owner) external view override returns (uint256) {
        return ownershipTokenCount[owner];
    }

    /*
     * @dev Returns the total number of tokens in circulation.
     */
    function totalSupply() external view override returns (uint256){
        return kitties.length;
    }
    /*
     * @dev Returns the name of the token.
     */
    function catName() external view override returns (string memory){
        return name;
    }
    /*
     * @dev Returns the symbol of the token.
     */
    function catSymbol() external view override returns (string memory) {
        return symbol;
    }
    /**
     * @dev Returns the owner of the `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function ownerOf(uint256 tokenId) external view override returns (address){
        require(kittyIndexToOwner[tokenId] != address(0));
        return kittyIndexToOwner[tokenId];
    }

    function transfer(address _to,uint256 _tokenId) external {

        require(_to != address(0));
        require(_to != address(this));
        require(_owns(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 the transfer event
        emit Transfer(_from, _to, tokenId);

    }

 }   

1 Like

Should it be owner instead of _owns?

Hey @Mickey_McClimon, hope you are well.

The only part where the _owns keyword is declared is here:
image

Unless its declared on the Ownable contract, if not, you could just remove it.

Also I advice you to use a revert message, that will make your life easy when testing the contract and triggering one of them. For Example:
require(_to != address(0), "_to can't be a zero address");

Carlos Z

1 Like

Been doing very well! Hope you are to my man! thank you so much for the quick response!!! your rock! So after removing the_owns as its not in the Ownable.sol file. It gave me a bunch of errors which I was able to get most but these Iā€™ve never seen beforeā€¦

pragma solidity >=0.4.22 <0.9.0;

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

 contract Kittycontract is IERC721, Ownable {
    
    // Gen 0 Creation Limit
    uint256 public constant CREATION_LIMIT_GEN0 = 10;

    // Token name
    string public constant override name = "MickeyKitties";

    // Token symbol
    string public constant override symbol = "GG";

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


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

    Kitty[] kitties;

    mapping (uint256 => address) public kittyIndexToOwner; // tokenId => kitty owner
    mapping (address => uint) ownershipTokenCount; //count of how many kitties each owner has

    uint256 public gen0Counter;


    function getKitty(uint256 _id) external view returns (
        uint256 genes,
        uint256 birthTime,
        uint256 momId,
        uint256 dadId,
        uint256 generation
    )
    {
        Kitty storage kitty = kitties[_id];

        birthTime = uint256(kitty.birthTime);
        momId = uint256(kitty.momId);
        dadId = uint256(kitty.dadId);
        generation = uint256(kitty.generation);
        genes = kitty.genes;
    }
    
    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 _momId,
        uint256 _dadId,
        uint256 _generation,
        uint256 _genes,
        address _owner
    )  private returns (uint256) {
        Kitty memory _kitty = Kitty({
            genes: _genes,
            birthTime: uint64(block.timestamp),
            momId: uint32(_momId),
            dadId: uint32(_dadId),
            generation: uint16(_generation)
        });

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

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

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

        return newKittenId;
    }

     //Returns the number of tokens in ``owner``'s account.
    function balanceOf(address owner) external view override returns (uint256) {
        return ownershipTokenCount[owner];
    }

    /*
     * @dev Returns the total number of tokens in circulation.
     */
    function totalSupply() external view override returns (uint256){
        return kitties.length;
    }
    /*
     * @dev Returns the name of the token.
     */
    function catName() external view  returns (string memory){
        return name;
    }
    /*
     * @dev Returns the symbol of the token.
     */
    function catSymbol() external view  returns (string memory) {
        return symbol;
    }
    /**
     * @dev Returns the owner of the `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function ownerOf(uint256 tokenId) external view override returns (address){
        require(kittyIndexToOwner[tokenId] != address(0));
        return kittyIndexToOwner[tokenId];
    }

    function transfer(address _to,uint256 _tokenId) external override {

        require(_to != address(0), "_to cant be a zero address");
        require(_to != address(this));
        require(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 the transfer event
        emit Transfer(_from, _to, tokenId);

    }

 }   

1 Like

So, I got the require statement right, that was the wrong wording, but for the other problem Iā€™ve never seen Operator not the compatible and different number of components on the left-hand side before, should I be using like .sub? Thanks so much again for the help you really rock man!!! @thecil

// SPDX-License-Identifier: MIT
pragma solidity >=0.4.22 <0.9.0;

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

contract Kittycontract is IERC721, Ownable {
   
   // Gen 0 Creation Limit
   uint256 public constant CREATION_LIMIT_GEN0 = 10;

   // Token name
   string public constant override name = "MickeyKitties";

   // Token symbol
   string public constant override symbol = "GG";

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


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

   Kitty[] kitties;

   mapping (uint256 => address) public kittyIndexToOwner; // tokenId => kitty owner
   mapping (address => uint) ownershipTokenCount; //count of how many kitties each owner has

   uint256 public gen0Counter;


   function getKitty(uint256 _id) external view returns (
       uint256 genes,
       uint256 birthTime,
       uint256 momId,
       uint256 dadId,
       uint256 generation
   )
   {
       Kitty storage kitty = kitties[_id];

       birthTime = uint256(kitty.birthTime);
       momId = uint256(kitty.momId);
       dadId = uint256(kitty.dadId);
       generation = uint256(kitty.generation);
       genes = kitty.genes;
   }
   
   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 _momId,
       uint256 _dadId,
       uint256 _generation,
       uint256 _genes,
       address _owner
   )  private returns (uint256) {
       Kitty memory _kitty = Kitty({
           genes: _genes,
           birthTime: uint64(block.timestamp),
           momId: uint32(_momId),
           dadId: uint32(_dadId),
           generation: uint16(_generation)
       });

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

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

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

       return newKittenId;
   }

    //Returns the number of tokens in ``owner``'s account.
   function balanceOf(address owner) external view override returns (uint256) {
       return ownershipTokenCount[owner];
   }

   /*
    * @dev Returns the total number of tokens in circulation.
    */
   function totalSupply() external view override returns (uint256){
       return kitties.length;
   }
   /*
    * @dev Returns the name of the token.
    */
   function catName() external view  returns (string memory){
       return name;
   }
   /*
    * @dev Returns the symbol of the token.
    */
   function catSymbol() external view  returns (string memory) {
       return symbol;
   }
   /**
    * @dev Returns the owner of the `tokenId` token.
    *
    * Requirements:
    *
    * - `tokenId` must exist.
    */
   function ownerOf(uint256 tokenId) external view override returns (address){
       require(kittyIndexToOwner[tokenId] != address(0));
       return kittyIndexToOwner[tokenId];
   }

   function transfer(address _to,uint256 _tokenId) external override {

       require(_to != address(0), "_to cant be a zero address");
       require(_to != address(this), "not the same address as _to");
       require(kittyIndexToOwner[_tokenId] == msg.sender);
   }


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

       kittyIndexToOwner[tokenId] = _to;

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

       // Emit the transfer event
       emit Transfer(_from, _to, tokenId);

   }

}   

1 Like

Sorry man, I do not understand your question, maybe if you explain it in detail i can help you with it :nerd_face:

Carlos Z

1 Like