Assignment - Get Kitty

getKitty Solution

    function getKitty(uint256 _kittyId) public view returns(Kitty memory) {
        Kitty memory returnKitty = kitties[_kittyId];
        return returnKitty;
    }   

I have some error and don’t know why?

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

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

  contract Kittycontract is IERC721 {
    
     using SafeMath for uint256;

     string public TokenName = "KittyCoin";
     string public TokenSymbol = "KTC";
     uint256 TokenAmount;

     mapping (uint256 => address) kittyIndexToOwner;   //owner of token
     mapping (address => uint256) ownerShipTokenCount; //token balance

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

     Kitty[] kitties;

     function crateKitty (uint256 _momId, uint256 _dadId, uint256 _generation, uint256 _gens,  address _owner  ) public returns (uint256) { // vraca cat ID 

        // kreiramo novi struct object using the name of the struct, pa zagrade kao function call, pa onda viticaste kao object 
        Kitty memory _kitty = Kitty({gens: _gens, birthTime: uint64(block.timestamp), momId: uint32(_momId), dadId: uint32(_dadId), generation: uint16(_generation)});

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

        _transfer(address(0), _owner, newKittyID);
     }

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

    function totalSupply() override external view returns (uint256 total){
         total = TokenAmount;
    }

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

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

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

    function transfer(address to, uint256 tokenId) override external{
        require(to != address(0), "cannot be the zero address");
        require(to != address(this), "can not be the contract address");
        require(kittyIndexToOwner[tokenId] == msg.sender);

        _transfer(msg.sender, to, tokenId);

        emit 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);
    }



}

Hey @Lane11, hope you are well.

Try with this:

     function crateKitty (uint256 _momId, uint256 _dadId, uint256 _generation, uint256 _gens,  address _owner  ) public returns (uint256) { // vraca cat ID 

        // kreiramo novi struct object using the name of the struct, pa zagrade kao function call, pa onda viticaste kao object 
        Kitty memory _kitty = Kitty({gens: _gens, birthTime: uint64(block.timestamp), momId: uint32(_momId), dadId: uint32(_dadId), generation: uint16(_generation)});
        
        uint256 newKittyID = kitties.length; // will be the index position before push the new kitty
        kitties.push(_kitty); // we push the new kitty, the index should be the same than newKittyID;
        _transfer(address(0), _owner, newKittyID);
     }

Carlos Z

2 Likes

There’s an easy (but not descriptive) way to do it which is:

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

But if you want to be more descriptive with your output, then I have done:

    function getKitty(uint256 _kittyId) external view returns (uint16 _genes, uint64 _birthTime, uint32 _mumId, uint32 _dadId, uint16 _generation) {
        require(_kittyId < kitties.length);
        return (kitties[_kittyId].genes, kitties[_kittyId].birthTime, kitties[_kittyId].mumId, kitties[_kittyId].dadId, kitties[_kittyId].generation);
    }
1 Like

A quick implementation on the first try:

    function getKitty(uint _kittyId) public view returns(uint dna_, uint birthTime_, uint momId_, uint dadId_, uint generation_) {
        Kitty storage kittyInfo = kitties[_kittyId];
        dna_ = kittyInfo.dna;
        birthTime_ = kittyInfo.birthTime;
        momId_ = kittyInfo.momId;
        dadId_ = kittyInfo.dadId;
        generation_ = kittyInfo.generation;
    }
1 Like
function getFishy(uint256 _tokenId) external view 
    returns (uint256 momId, 
             uint256 dadId,
             uint256 generation,
             uint256 genes,
             address owner) {

        address _currentOwner = ownerToken[_tokenId];

        require(_currentOwner != address(0), "Ensure token exists");
        require(fishies.length > 0, "Ensure Fishies exist");

        return(fishies[_tokenId].momId,
               fishies[_tokenId].dadId, 
               fishies[_tokenId].generation, 
               fishies[_tokenId].genes , 
               _currentOwner);
    }
1 Like
function getKitty(uint256 id) external view returns (
        
        uint256 birthTime,
        uint256 motherID,
        uint256 fatherID,
        uint256 generation,
        uint256 genes
        ){
        Kitty storage kitty = kitties[id]; //save as a pointer

        birthTime = uint256(kitty.birthTime);
        motherID = uint256(kitty.motherID);
        fatherID = uint256(kitty.fatherID);
        generation = uint256(kitty.generation);
        genes = kitty.genes;
    }
1 Like

Response SC from getKitty()

function getKitty(uint256 tokenId) public view returns (Kitty memory){
    require(owners[tokenId] != address(0), "Token does not exists!");
    Kitty storage kitty = kitties[tokenId];

    return kitty;
  }
KittyContract.sol

// SPDX-License-Identifier: MIT

pragma solidity >=0.5.0 < 0.8.11;

import “@openzeppelin/contracts/utils/math/SafeMath.sol”;

import “@openzeppelin/contracts/access/Ownable.sol”;

import “./IERC721.sol”;

contract KittyContract is IERC721, Ownable {

using SafeMath for uint256;

string private _name;

string private _symbol;

uint256 public gen0Counter;

uint256 public gen0MintLimit = 9;

struct Kitty {

uint256 dna;

uint64 spawnedAt;

uint32 momId;

uint32 dadId;

uint16 generation;

}

Kitty[] kitties;

mapping(address => uint256) public balances;

mapping(uint256 => address) public owners;

event KittySpawned(uint256 kittyId, uint256 dna, address owner, uint256 momId, uint256 dadId);

constructor(string memory name_, string memory symbol_) {

_name = name_;

_symbol = symbol_;

}

function balanceOf(address owner) external override view returns (uint256 balance) {

balance = balances[owner];

}

function totalSupply() external override view returns (uint256 total) {

total = kitties.length;

}

function name() external override view returns (string memory tokenName) {

tokenName = _name;

}

function symbol() external override view returns (string memory tokenSymbol) {

tokenSymbol = _symbol;

}

function ownerOf(uint256 tokenId) external override view returns (address owner) {

owner = owners[tokenId];

require(owner != address(0), "Token id does not exists!");

}

function createKittyGen0(uint256 _dna) public onlyOwner {

require(gen0Counter < gen0MintLimit, "Minting Limit reached for Gen0");

gen0Counter = gen0Counter.add(1);



_createKitty(_dna, 0, 0, 0, msg.sender);

}

function _createKitty(

uint256 _dna,

uint256 _momId,

uint256 _dadId,

uint256 _generation,

address _owner

) private returns (uint256){

Kitty memory kitty = Kitty({

  dna: _dna,

  spawnedAt: uint64(block.timestamp),

  momId: uint32(_momId),

  dadId: uint32(_dadId),

  generation: uint16(_generation)

});

kitties.push(kitty);

uint256 newKittyId = (kitties.length).sub(1);



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

emit KittySpawned(newKittyId, _dna, _owner, _momId, _dadId);



return newKittyId;

}

function getKitty(uint256 tokenId) public view returns (Kitty memory){

require(owners[tokenId] != address(0), "Token does not exists!");

Kitty storage kitty = kitties[tokenId];

return kitty;

}

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

require(to != address(0), "Recieving address cannot be dead address!");

require(to != address(this), "Cannot send to the contract!");

require(owners[tokenId] == msg.sender, "Token Id must belong to the message sender!");

_transfer(msg.sender, to, tokenId);

}

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

if(_from != address(0)) {

  balances[_from] = balances[_from].sub(1);

}

owners[_tokenId] = _to;

balances[_to] = balances[_to].add(1);

emit Transfer(_from, _to, _tokenId);

}

}

2 Likes

I run into this error whenever i run instance.createKittyGen0()

truffle(development)> instance.createKittyGen0(1001)
Uncaught:
StatusError: Transaction: 0x29a95d4f622930dc8ddff2b8c6650cdac27842b2906cc5708f6469c25df7ac9e exited with an error (status 0). 
    at evalmachine.<anonymous>
    at sigintHandlersWrap (node:vm:268:12)
    at Script.runInContext (node:vm:137:14)
    at runScript (/usr/local/lib/node_modules/truffle/build/webpack:/packages/core/lib/console.js:364:1)
    at Console.interpret (/usr/local/lib/node_modules/truffle/build/webpack:/packages/core/lib/console.js:379:1)
    at bound (node:domain:421:15)
    at REPLServer.runBound [as eval] (node:domain:432:12)
    at REPLServer.onLine (node:repl:891:10)
    at REPLServer.emit (node:events:520:28)
    at REPLServer.emit (node:domain:475:12)
    at REPLServer.Interface._onLine (node:readline:487:10)
    at REPLServer.Interface._line (node:readline:864:8)
    at REPLServer.Interface._ttyWrite (node:readline:1216:14)
    at REPLServer.self._ttyWrite (node:repl:986:9) {
  tx: '0x29a95d4f622930dc8ddff2b8c6650cdac27842b2906cc5708f6469c25df7ac9e',
  receipt: {
    transactionHash: '0x29a95d4f622930dc8ddff2b8c6650cdac27842b2906cc5708f6469c25df7ac9e',
    transactionIndex: 0,
    blockNumber: 36,
    blockHash: '0xa86c80ecb49e049ec3928af0d613133310b8facd41b26c8bdc60ab599d1d396f',
    from: '0xc329b7cdc69020810a4375e8a011ff1d5c6e2bec',
    to: '0x462c32f3912c1617c900fcc9865023ddb75bda3b',
    cumulativeGasUsed: 24183,
    gasUsed: 24183,
    contractAddress: null,
    logs: [],
    logsBloom: '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
    status: false,
    effectiveGasPrice: '0x9582daab',
    type: '0x2',
    rawLogs: []
  },
  reason: undefined,
  hijackedStack: 'StatusError: Transaction: 0x29a95d4f622930dc8ddff2b8c6650cdac27842b2906cc5708f6469c25df7ac9e exited with an error (status 0). \n' +
    '     Please check that the transaction:\n' +
    '     - satisfies all conditions set by Solidity `require` statements.\n' +
    '     - does not trigger a Solidity `revert` statement.\n' +
    '\n' +
    '    at Object.receipt (/usr/local/lib/node_modules/truffle/build/webpack:/packages/contract/lib/handlers.js:128:1)\n' +
    '    at processTicksAndRejections (node:internal/process/task_queues:96:5)\n' +
    '    at Function.start (/usr/local/lib/node_modules/truffle/build/webpack:/packages/contract/lib/override.js:49:1)'
}
truffle(development)> 


Below is my Kitty contract

pragma solidity ^0.8.10;

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

contract kittyContract is IERC721, Ownable{
   uint256 public constant CREATION_LIMIT_GEN0 = 10;
   string public constant tokenSymbol = "CK";
   string public constant tokenName = "CodedKitties";
  
  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 kittyTokenOwner;

        uint256 public gen0Counter;

        function createKittyGen0(uint256 _genes) public isOwner 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(uint _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)
        });

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

        uint256 newKittenId = kitties.length -1;


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

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

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

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

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

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

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

   function transfer(address to, uint256 tokenId) external{

       require(to != address(0));
       require(to != address(this));
    
    _transfer(msg.sender, to, tokenId);
   }

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

       kittyTokenOwner[_tokenId] = _to;

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

    //    emit transfer event

    emit Transfer(_from, _to, _tokenId);


   }

}


below is my ownable contract

pragma solidity ^0.8.10;

contract Ownable {

    address private owner;
    
    // event for EVM logging
    event OwnerSet(address indexed oldOwner, address indexed newOwner);
    
    // modifier to check if caller is owner
    modifier isOwner() {
        // If the first argument of 'require' evaluates to 'false', execution terminates and all
        // changes to the state and to Ether balances are reverted.
        // This used to consume all gas in old EVM versions, but not anymore.
        // It is often a good idea to use 'require' to check if functions are called correctly.
        // As a second argument, you can also provide an explanation about what went wrong.
        require(msg.sender == owner, "Caller is not owner");
        _;
    }
    
    /**
     * @dev Set contract deployer as owner
     */
    constructor() {
        owner = msg.sender; // 'msg.sender' is sender of current call, contract deployer for a constructor
        emit OwnerSet(address(0), owner);
    }

    /**
     * @dev Change owner
     * @param newOwner address of new owner
     */
    function changeOwner(address newOwner) public isOwner {
        emit OwnerSet(owner, newOwner);
        owner = newOwner;
    }

    /**
     * @dev Return owner address 
     * @return address of owner
     */
    function getOwner() external view returns (address) {
        return owner;
    }
}
1 Like

I think you should call in the truffle console.

truffle(development)> await instance.createKittyGen0(1001)

Carlos Z

It still gives the same error

Hi guys, can you give me a hand with the following error I have?.
As much as I check again and again I can not identify the error in the attached file

. By the way, the sol files are using the same compilator.

On the other hand, I found this

However, the truffle-config.js file is configured for the version: "0.5.12", compiler.

1 Like

Maybe one of your require is getting triggered, try to add an error message on them, here is an example, try to fill the rest of them in your contract and run the function again, this time, you should have an error message the you can follow to have a better picture of the issue.

     function ownerOf(uint256 tokenId) external view returns (address ){
          require(kittyTokenOwner[tokenId] != address(0), "ownerOf: zero address");
           return kittyTokenOwner[tokenId];
   }

   function transfer(address to, uint256 tokenId) external{

       require(to != address(0), "transfer: cannot transfer to zero address");
       require(to != address(this), "transfer: cannot transfer to contract address");
    
    _transfer(msg.sender, to, tokenId);
   }

Carlos Z

Hey @cgironda, hope you are well.

Each of the console error mention “invalid implicit conversion from AAA to BBB”

You might want to check the order you are providing the arguments to the function, quick example:

function something(address _address, uint256 _number, string memory _string){...}

function doSomething(uint256 _a, string memory _words){
// correct way, just provide the arguments in the same order of the function header
// an address, a uint, a string
something(msg.sender, 5, "when moon");
}

Carlos Z

Hi @thecil, thank you for your reply to answer my question.

Based on your explanation I found I declared one of my parameters as an integer.
Now the program runs very well.

Thank you very much!

1 Like

I’ve fixed it bro, the issue was coming from the ownable contract

1 Like
function getPenguin(uint256 _id) external view returns (
        uint256 genes,
        uint256 birthTime,
        uint256 mumId,
        uint256 dadId,
        uint256 generation
        //address owner
    )
    {
        Penguin storage penguin = penguins[_id];

        birthTime = uint256(penguin.birthTime);
        mumId = uint256(penguin.mumId);
        dadId = uint256(penguin.dadId);
        generation = uint256(penguin.generation);
        genes = penguin.genes;
    }
1 Like

Ownable.sol

pragma solidity ^0.5.12;

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

  constructor() public {
    owner = msg.sender;
  }
}

Kittycontract.sol

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

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

contract Kittycontract is IERC721, Ownable {
  string public constant Name = "DemoKitties";
  string public constant Symbol = "DK";
  uint256 public constant CREATE_LIMIT_GEN0 = 10;

  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[] private allKitties; // index => kitty id (token id)

  mapping (address => uint256) ownerTokenBalance; // get uint256 amount (token kitty count) of owner address
  mapping (uint256 => address) public kittyIndexToOwner; // get owner address of uint256 kitty id (token id)
  
  uint256 public gen0Counter;

  function createKittenGen0(uint256 _genes) public onlyOwner {
    require(gen0Counter < CREATE_LIMIT_GEN0, "Max number of Generation0 kittens reached");
    gen0Counter++;

    _createKitty(0, 0, 0, _genes, msg.sender); // no parents, owned by the contract
  }

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

    uint256 newKittenId = allKitties.push(_kitty) -1; // zero based Id

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

    _transfer(address(0), _owner, newKittenId); // address(0): birth of new kitten to owner

    return newKittenId;
  }

  function getKitty(uint256 _id) external view returns(
    uint256 genes, uint256 birthTime,
    uint256 mumId, uint256 dadId,
    uint256 generation
  ) {
    Kitty storage kitty = allKitties[_id]; // storage is a pointer to the original mapping, memory creates a local copy

    genes = kitty.genes;
    birthTime = uint256(kitty.birthTime);
    mumId = uint256(kitty.mumId);
    dadId = uint256(kitty.dadId);
    generation = uint256(kitty.generation);
  }


  // ---

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

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

  function name() public view returns (string memory) {
    return Name;
  }

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

  function ownerOf(uint256 _tokenId) external view returns (address) {
    address owner = kittyIndexToOwner[_tokenId];
    require(owner != address(0), "No owner of not existing address");
    return owner;
  }

  function transfer(address _to, uint256 _tokenId) external {
    require(_to != address(0), "TO address must be defined.");
    require(_to != address(this), "Cannot transfer to the contract itself");
    require(_to != msg.sender, "Cannot send to yourselves");
    require(owns(msg.sender, _tokenId), "Cannot send token you not own");

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

  function _transfer(address _from, address _to, uint256 _tokenId) internal {
    ownerTokenBalance[_to]++;
    if (_from != address(0)) {
      ownerTokenBalance[_from]--;
    }
    kittyIndexToOwner[_tokenId] = _to;

    emit Transfer(_from, _to, _tokenId);
  }

  function owns(address claimant, uint256 tokenId) internal view returns (bool) {
    return kittyIndexToOwner[tokenId] == claimant;
  }
}
1 Like

,TypeError: Different number of components on the left hand side (1) than on the right hand side (0).
–> project:/contracts/kittycontract.sol:65:9:
|
65 | uint256 newKittienId = Kitties.push(_Kitty) - 1;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

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

truffle(development)> instance.getKitty(0)
Result {
‘0’: BN {
negative: 0,
words: [ 1001, <1 empty item> ],
length: 1,
red: null
},
‘1’: BN {
negative: 0,
words: [ 42456294, 24, <1 empty item> ],
length: 2,
red: null
},
‘2’: BN {
negative: 0,
words: [ 0, <1 empty item> ],
length: 1,
red: null
},
‘3’: BN {
negative: 0,
words: [ 0, <1 empty item> ],
length: 1,
red: null
},
‘4’: BN {
negative: 0,
words: [ 0, <1 empty item> ],
length: 1,
red: null
}
}