Assignment ERC721

Having an issue with returnData from the IERC721REciever.sol, Not sure if it is that or if it is my kittycontract.

The Error I get is: image

pragma solidity ^0.8.1;


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

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


contract Kittycontract is IERC721{
    using SafeMath for uint256;
        
    uint256 public constant CREATION_LIMIT_GEN0 = 10;
    string public constant Name = "EbrahimsKitties";
    string public constant Symbol = "EK";

    bytes4 internal constant MAGIC_ERC721_RECEIVED = bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"));

    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 (uint256 => address) kittyIndexToOwner;
    mapping(address => uint256) ownershipTokenCount;
    mapping(uint => address) public kittyIndexToApproved;
    mapping(address => mapping (address => bool)) _operatorApprovals;

    uint256 public gen0Counter;

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

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

    }

    function createKittyGen0(uint256 _genes) public  {
        require(gen0Counter < CREATION_LIMIT_GEN0);
        gen0Counter = gen0Counter.add(1);
        _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.sub(1);

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

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

        return newKittenId;
     }

    /**
     * @dev Returns the number of tokens in ``owner``'s account.
     */
    function balanceOf(address owner) external override view returns (uint256 balance){
        return ownershipTokenCount[owner];
    }
    
     /*
     * @dev Returns the total number of tokens in circulation.
     */
    function totalSupply() external override view returns (uint256 total){
        return kitties.length;

    }

    /*
     * @dev Returns the name of the token.
     */
    function name() external override pure returns (string memory tokenName){
        return Name;
    }

      /*
     * @dev Returns the symbol of the token.
     */
    function symbol() external override pure returns (string memory tokenSymbol){
        return Symbol;
    }

    /**
     * @dev Returns the owner of the `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function ownerOf(uint256 tokenId) external override view returns (address owner){
        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) override external{
        require(_owns(msg.sender, tokenId));
        require(to != address(0));
        require(to != address(this));
        
        _transfer(msg.sender, to, tokenId);
    }

        /// @notice Change or reaffirm the approved address for an NFT
    /// @dev The zero address indicates there is no approved address.
    ///  Throws unless `msg.sender` is the current NFT owner, or an authorized
    ///  operator of the current owner.
    /// @param _approved The new approved NFT controller
    /// @param _tokenId The NFT to approve
    function approve(address _approved, uint256 _tokenId) override external{
        require(_owns(msg.sender, _tokenId));
       _approve(_tokenId, _approved);
        emit Approval(msg.sender, _approved, _tokenId);
    }

        /// @notice Enable or disable approval for a third party ("operator") to manage
    ///  all of `msg.sender`'s assets
    /// @dev Emits the ApprovalForAll event. The contract MUST allow
    ///  multiple operators per owner.
    /// @param _operator Address to add to the set of authorized operators
    /// @param _approved True if the operator is approved, false to revoke approval
    function setApprovalForAll(address _operator, bool _approved) override external{
        _operatorApprovals[msg.sender][_operator] = _approved;
        emit ApprovalForAll(msg.sender, _operator, _approved);
    }

       /// @notice Get the approved address for a single NFT
    /// @dev Throws if `_tokenId` is not a valid NFT.
    /// @param _tokenId The NFT to find the approved address for
    /// @return The approved address for this NFT, or the zero address if there is none
    function getApproved(uint256 _tokenId) override external view returns (address){
        require(_tokenId < kitties.length);
        return kittyIndexToApproved[_tokenId];
    }

    
    /// @notice Query if an address is an authorized operator for another address
    /// @param _owner The address that owns the NFTs
    /// @param _operator The address that acts on behalf of the owner
    /// @return True if `_operator` is an approved operator for `_owner`, false otherwise
    function isApprovedForAll(address _owner, address _operator) override public view returns (bool){
        return _operatorApprovals[_owner][_operator];
    }

    
    /// @notice Transfer ownership of an NFT -- THE CALLER IS RESPONSIBLE
    ///  TO CONFIRM THAT `_to` IS CAPABLE OF RECEIVING NFTS OR ELSE
    ///  THEY MAY BE PERMANENTLY LOST
    /// @dev Throws unless `msg.sender` is the current owner, an authorized
    ///  operator, or the approved address for this NFT. Throws if `_from` is
    ///  not the current owner. Throws if `_to` is the zero address. Throws if
    ///  `_tokenId` is not a valid NFT.
    /// @param _from The current owner of the NFT
    /// @param _to The new owner
    /// @param _tokenId The NFT to transfer
    function transferFrom(address _from, address _to, uint256 _tokenId) override external{
        require(_to != address(0));
        require(msg.sender == _from || _approvedFor(msg.sender, _tokenId) || isApprovedForAll(_from, msg.sender));
        require(_owns(_from, _tokenId));
        require(_tokenId < kitties.length);
        
        _transfer(_from, _to, _tokenId);

        }


    function _isContract (address _to ) view internal returns (bool) {
        uint32 size; 
        assembly{
            size := extcodesize(_to)
        }

        return size > 0; 
    }

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

    function _transfer(address _from, address _to, uint256 _tokenId) internal {
        ownershipTokenCount[_to] = ownershipTokenCount[_to].add(1);
        kittyIndexToOwner[_tokenId] = _to;

        if(_from != address(0)){
                ownershipTokenCount[msg.sender] = ownershipTokenCount[msg.sender].sub(1);
                delete kittyIndexToApproved[_tokenId];
        }
        emit Transfer(_from, _to, _tokenId);
    }

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

    function _approve (uint256 _tokenId, address _approved) internal {
        kittyIndexToApproved[_tokenId] = _approved;
    }  

    function _safeTransfer(address _from, address _to, uint256 _tokenId, bytes memory _data) internal {
        _transfer(_from, _to, _tokenId);
        require(_checkERC721Support(_from, _to, _tokenId, _data));
    }

    function _checkERC721Support(address _from, address _to, uint256 _tokenId, bytes memory _data) internal returns (bool) {
        if( !_isContract(_to)){
            return true;
        } 
        ///calling onERC721Recieve Function in the _to Contract 
        bytes4 returnData = IERC721Receiver(_to).onERC721Received(msg.sender, _from, _tokenId, _data);
        return returnData == MAGIC_ERC721_RECEIVED;

        /// Check return value

    }

        /// @notice Transfers the ownership of an NFT from one address to another address
    /// @dev Throws unless `msg.sender` is the current owner, an authorized
    ///  operator, or the approved address for this NFT. Throws if `_from` is
    ///  not the current owner. Throws if `_to` is the zero address. Throws if
    ///  `_tokenId` is not a valid NFT. When transfer is complete, this function
    ///  checks if `_to` is a smart contract (code size > 0). If so, it calls
    ///  `onERC721Received` on `_to` and throws if the return value is not
    ///  `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`.
    /// @param _from The current owner of the NFT
    /// @param _to The new owner
    /// @param _tokenId The NFT to transfer
    /// @param data Additional data with no specified format, sent in call to `_to`
    function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes calldata data) override external{

    }

    /// @notice Transfers the ownership of an NFT from one address to another address
    /// @dev This works identically to the other function with an extra data parameter,
    ///  except this function just sets data to "".
    /// @param _from The current owner of the NFT
    /// @param _to The new owner
    /// @param _tokenId The NFT to transfer
    function safeTransferFrom(address _from, address _to, uint256 _tokenId) override external{

    }

    

}
pragma solidity ^0.8.0;

interface IERC721Receiver {
    function onERC721Received(address _operator, address _from, uint _tokenId, bytes calldata _data) external returns (bytes4);
}
1 Like

Hereā€™s my assignment

Kittycontract.sol
// 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 private _name = "KittyCutie";
    string private _symbol = "KTCT";
    
    struct Kitty {
        uint256 genes;
        uint64 birthTime;
        uint32 mumId;
        uint32 dadId;
        uint16 generation;
    }

    Kitty[] kitties;

    mapping(address => uint256) private _kittyBalance;
    mapping(uint256 => address) private _kittyOwners;
    
    function balanceOf(address owner) public view virtual override returns (uint256) {
        require(owner != address(0), "ERC721: balance query for the zero address");
        return _kittyBalance[owner];
    }

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

    function name() public view virtual override returns (string memory) {
        return _name;
    }

    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    function ownerOf(uint256 tokenId) public view virtual override returns (address) {
        address owner = _kittyOwners[tokenId];
        require(owner != address(0), "ERC721: owner query for nonexistent token");
        return owner;
    }


    function ownedBy(address claimant, uint256 tokenId) internal view returns(bool) {
        return _kittyOwners[tokenId] == claimant;
    }

    function transfer(address to, uint256 tokenId) public override {
        require(address(this) != to);
        require(address(0) != to);
        require(ownedBy(msg.sender, tokenId));

        _transfer(msg.sender, to, tokenId);
    }

    function _transfer(address from, address to, uint256 tokenId) internal virtual {
        if(from != address(0)){
            _kittyBalance[from]--;
        }
        _kittyBalance[to]++;
        _kittyOwners[tokenId] = to;
        
        emit Transfer(from, to, tokenId);
    }
}

Problem encountered: I had errors because the ā€œESLintā€ extension was enabled from creating previous projects with React and Next.js (Disable some extensions that are not needed before coding :v:)

Also, I copied some of the functions from ERC721 of openzeppelin, which had some differences from the functions to be answered for the assignment. Hope thatā€™s okay

Hi, @AdamFortuna (or anyone esle) I have deployed the assignment but I canā€™t quite interact with the contract itself.

When I do instance.name it shows this instead of the actual name, any suggestions on how to fix this? Thank you so much!

image

LOL nevermind this question :sweat_smile: I just forgot to put ā€œ()ā€ at the end of instance.name

Sorry for the trouble :v:

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

 import "./ERC721.sol";

 contract SupplyChainProtocol is ERC721 {
    string constant name = "Supply Chain Protocol";
    string constant symbol = "SCP"; 
 
  struct Order{
      uint256 id;
      uint64 timeStamp;
      uint64 cost;
      string productName;
      string description;
      uint64 leadTime_in_days;
    }
    Order[] orderVolume;
   
    mapping(address => uint256) private balances;
    mapping(address => uint256) orders;
    mapping(address => uint256) OrderIncites;
    mapping(uint256 => address) orderIdMapping;

   
    function totalSupply() public view returns (uint256 total){
        return orderVolume.length;
    }   
    function balanceOf(address owner) external view virtual override returns (uint256 balance){
        return OrderIncites[owner];
    }
    function ownerOf(uint256 tokenId) external view virtual override returns (address owner){
        return orderIdMapping[tokenId];
        
    }
    
    function transfer(address from, address to, uint256 tokenId) external{
        require(address(to) != address(0));
        require(address(from) != address(0));
        require(orderIdMapping[tokenId]==msg.sender);
        emit Transfer(msg.sender, to, tokenId);
    }
    function _transfer(address _from, address _to, uint256 _tokenId) override internal {
        balances[_to]++;
        _to=orderIdMapping[_tokenId];
        if(_from != address(0)) {
            balances[_from]--;
        }
        emit Transfer(_from, _to, _tokenId);

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

image

Here is my code

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

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

 abstract contract KittyContract is IERC721 {

  using SafeMath for uint256;

  mapping(address => uint256) ownershipTokenCount;
  mapping(uint256 => address) private _owners;

  mapping(address => Kitties) private kitties;


  uint256 private _totalSupply;
  string private _name;
  string private _symbol;

struct Kitties{
  uint256 tokenId;

}

constructor(string memory name_, string memory symbol_) {
  _name = name_;
  _symbol = symbol_;

}


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

  function totalSupply() external view override returns (uint256 total) {
    return _totalSupply;

  }

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

  function ownerOf(uint256 _tokenId) external view override returns (address) {
    address owner = _owners[_tokenId];
    require(owner != address(0), "ERC721: owner query for nonexistent token");
    return owner;
  }

  function transfer(address _from,  address _to, uint256 tokenId) external virtual {
    require(address(_to) != address(this), "to cannot be the contract address" );
    require(address(_to) != address(0),"to cannot be the zero address" );
    require(_owners[tokenId] == msg.sender);

    ownershipTokenCount[_from];
    ownershipTokenCount[_to] = ownershipTokenCount[_to].add(1);
    _owners[tokenId] = _to;

    emit Transfer(msg.sender, _to, tokenId);
     
  }

}

@filip
I am having a problem installing SafeMath wwith from zeppelin - I am getting an error from a previous library I was trying to install for generating a color library.

up to date, audited 368 packages in 2s

51 packages are looking for funding
  run `npm fund` for details

# npm audit report

web3

Insecure Credential Storage - https://npmjs.com/advisories/877
No fix available
node_modules/web3
  @drizzle/store  *
  Depends on vulnerable versions of web3
  node_modules/@drizzle/store

2 low severity vulnerabilities

Some issues need review, and may require choosing
a different dependency.

ā€¦I ended up just making a copy of SafeMath into my contracts directory by hand and deleting some of those files I had tried to install from an nmp color library

How come you did not get an error stating you have to put your contract as abstract?

1 Like

Hi @Samuel1

The compiler is cannot find the contract " IERC721Metadata.sol" at the specified path.

Have you installed the @openzeppelin/contracts package locally or you downloaded all the contracts one by one?

Run npm i @openzeppelin/contracts and try again.

If you still get that error message, then I need to see the structure of your repo so just push your code on github and share the link.

Cheers,
Dani

Hello @Ebrahim_Elbagory! Wellcome.
In order to fully check your code i need to download it from github repo. Can you send me a link for testing it?

IERC721 Assignment

pragma solidity ^0.8.4;

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


contract Catcontract is IERC721 {
using SafeMath for uint256;

string private  constant Name = "KATKypto";
string private constant Symbol = "KATC";

struct Cat {
    uint256 genes;
    uint64 birthTime;
    uint32 mumId;
    uint32 dadId;
    uint16 generation;
}
Cat[] cats;
//      owner      amount
mapping(address => uint256) ownerTokenBalance;

//      tokenId    owner of cat
mapping(uint256 => address) public catIndexToOwner;

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

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

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

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

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

    function transfer(address to, uint256 tokenId) external override{
        require(to != address(0), "Cannot Send Tokens To This Address");
        require(to != address(this), "Cannot Send Tokens To This Address");
        require(owns(msg.sender, tokenId), "You Must Own The Token You Are Sending");

        ownerTokenBalance[to] = ownerTokenBalance[to].add(1);
        ownerTokenBalance[msg.sender] = ownerTokenBalance[msg.sender].sub(1);
        
        emit Transfer(msg.sender, to, tokenId);
    }

    function owns(address claimant, uint256 _tokenId) internal view returns (bool){
        return catIndexToOwner[_tokenId] == claimant;
    }

}
1 Like

Here is my code:

pragma solidity ^0.5.16;

import "./IERC721.sol";

contract Kittycontract is IERC721 {
    
    string public constant tokenName = "RichKitties";
    string public constant tokenSymbol= "RK";

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

    Kitty[] kitties;

    mapping (address => uint256) ownershipTokenCount; //maps from owner's address to how many tokens they own
    mapping (uint256 => address) public kittyIndexToOwner; //maps from kitties array index (tokenId?) to address of kitty owner

    /**
     * @dev Emitted when `tokenId` token is transfered from `from` to `to`.
     */
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
     */
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);

    /**
     * @dev Returns the number of tokens in ``owner``'s account.
     */
    function balanceOf(address _owner) external view returns (uint256 balance) { //external means you can't call it from within the contract
        return ownershipTokenCount[_owner];
    }
    /*
     * @dev Returns the total number of tokens in circulation.
     */
    function totalSupply() public view returns (uint256) {
        return kitties.length;
    }

    /*
     * @dev Returns the name of the token.
     */
    function name() external view returns (string memory) {
        return tokenName;
    }

    /*
     * @dev Returns the symbol of the token.
     */
    function symbol() external view returns (string memory) {
        return tokenSymbol;
    }

    /**
     * @dev Returns the owner of the `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function ownerOf(uint256 _tokenId) external view returns (address owner) {
        return kittyIndexToOwner[_tokenId]; //what does this mean? Is there just one tokenId? Or multiple?
    }


     /* @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 {
        require (_to != address(0), "Cannot transfer tokenId to zero address");
        require (_to != address(this), "Cannot transfer tokenId to contract address");
        require (_owns(msg.sender,_tokenId), "Cannot transfer tokenId if you don't own it");


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

    function _transfer(address _from, address _to, uint256 _tokenId) internal {
        ownershipTokenCount[_to]++;
        kittyIndexToOwner[_tokenId] = _to; //change ownership in the actual mapping

        if (_from != address(0)){
            ownershipTokenCount[_from]--;
        }
        //emit the transfer event
        emit Transfer(msg.sender, _to, _tokenId);
        }
    

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

}
1 Like

Iā€™m curious to know why we need an initial Migrations contract in order to deploy a second contract? Also curious to know why when I deploy to Ganache there are multiple transactions for each migration - at least 3 or 4 transactions when Iā€™m only deploying two contracts? Two of the transactions are obviously contract creation transactions, but the other 1 or 2 are ā€˜contract callsā€™ that donā€™t give up any other detail?

One more question - related to the getKitty() function. Why would you not just implement it like this:

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

This is obviously simpler and shorter than the solution in the video, and it seems to me to return all of the same information - perhaps I am missing something though? Thanks.

@filip, @dan-i
Hello Devs

I am interacting with my Kitty contract and it works for the getter functions like instance.name() and instance.symbol() but when I execute the createKittyGen0(100), I get errors in the terminal and the Ganache contracts says the IERC721 contract is not deployed.

Here is a link to my project on Github so I can get some help on this, thank you.
https://github.com/brlojam4932/bl_crytpKittiesProj.git

truffle(ganache)> instance.createKittyGen0(100)
Uncaught Error: Returned error: VM Exception while processing transaction: revert
    at evalmachine.<anonymous>:0:10
    at sigintHandlersWrap (vm.js:273:12)
    at Script.runInContext (vm.js:140:14)
    at runScript (C:\Users\benX\AppData\Roaming\npm\node_modules\truffle\build\webpack:\packages\core\lib\console.js:270:1)
    at Console.interpret (C:\Users\benX\AppData\Roaming\npm\node_modules\truffle\build\webpack:\packages\core\lib\console.js:285:1)
    at bound (domain.js:413:15)
    at REPLServer.runBound [as eval] (domain.js:424:12)
    at REPLServer.onLine (repl.js:817:10)
    at REPLServer.emit (events.js:315:20)
    at REPLServer.EventEmitter.emit (domain.js:467:12)
    at REPLServer.Interface._onLine (readline.js:337:10)
    at REPLServer.Interface._line (readline.js:666:8)
    at REPLServer.Interface._ttyWrite (readline.js:1010:14)
    at REPLServer.self._ttyWrite (repl.js:907:9)
    at ReadStream.onkeypress (readline.js:213:10)
    at ReadStream.emit (events.js:315:20)
    at ReadStream.EventEmitter.emit (domain.js:467:12)
    at emitKeys (internal/readline/utils.js:345:14)
    at emitKeys.next (<anonymous>)
    at ReadStream.onData (readline.js:1144:36) {
  data: {
    '0x104a8a9632f5250f935bdba284ae2ec2906a0185e6406c523f39747629692e03': { error: 'revert', program_counter: 1790, return: '0x' },
    stack: 'RuntimeError: VM Exception while processing transaction: revert\n' +
      '    at Function.RuntimeError.fromResults (C:\\Program Files\\WindowsApps\\GanacheUI_2.5.4.0_x64__5dg5pnz03psnj\\app\\resources\\static\\node\\node_modules\\ganache-core\\lib\\utils\\runtimeerror.js:94:13)\n' +  
      '    at BlockchainDouble.processBlock (C:\\Program Files\\WindowsApps\\GanacheUI_2.5.4.0_x64__5dg5pnz03psnj\\app\\resources\\static\\node\\node_modules\\ganache-core\\lib\\blockchain_double.js:627:24)\n' +       
      '    at runMicrotasks (<anonymous>)\n' +
      '    at processTicksAndRejections (internal/process/task_queues.js:93:5)',
    name: 'RuntimeError'
  },
  hijackedStack: 'Error: Returned error: VM Exception while processing transaction: revert\n' +
    '    at Object.ErrorResponse (C:\\Users\\benX\\AppData\\Roaming\\npm\\node_modules\\truffle\\build\\webpack:\\node_modules\\web3-core-helpers\\lib\\errors.js:28:1)\n' +
    '    at C:\\Users\\benX\\AppData\\Roaming\\npm\\node_modules\\truffle\\build\\webpack:\\node_modules\\web3\\node_modules\\web3-core-requestmanager\\lib\\index.js:303:1\n' +
    '    at C:\\Users\\benX\\AppData\\Roaming\\npm\\node_modules\\truffle\\build\\webpack:\\packages\\provider\\wrapper.js:107:1\n' +
    '    at XMLHttpRequest.request.onreadystatechange (C:\\Users\\benX\\AppData\\Roaming\\npm\\node_modules\\truffle\\build\\webpack:\\node_modules\\web3\\node_modules\\web3-providers-http\\lib\\index.js:98:1)\n' +    
    '    at XMLHttpRequestEventTarget.dispatchEvent (C:\\Users\\benX\\AppData\\Roaming\\npm\\node_modules\\truffle\\build\\webpack:\\node_modules\\xhr2-cookies\\dist\\xml-http-request-event-target.js:34:1)\n' +        
    '    at XMLHttpRequest.exports.modules.996763.XMLHttpRequest._setReadyState (C:\\Users\\benX\\AppData\\Roaming\\npm\\node_modules\\truffle\\build\\webpack:\\node_modules\\xhr2-cookies\\dist\\xml-http-request.js:208:1)\n' +
    '    at XMLHttpRequest.exports.modules.996763.XMLHttpRequest._onHttpResponseEnd (C:\\Users\\benX\\AppData\\Roaming\\npm\\node_modules\\truffle\\build\\webpack:\\node_modules\\xhr2-cookies\\dist\\xml-http-request.js:318:1)\n' +
    '    at IncomingMessage.<anonymous> (C:\\Users\\benX\\AppData\\Roaming\\npm\\node_modules\\truffle\\build\\webpack:\\node_modules\\xhr2-cookies\\dist\\xml-http-request.js:289:47)\n' +
    '    at IncomingMessage.emit (events.js:327:22)\n' +
    '    at IncomingMessage.EventEmitter.emit (domain.js:529:15)\n' +
    '    at endReadableNT (internal/streams/readable.js:1327:12)\n' +
    '    at processTicksAndRejections (internal/process/task_queues.js:80:21)'
}
truffle(ganache)>

ganache_window

Hi @bjamRez

The error is related to a require statement whose condition is not satisfied.
Checking the function you are calling I see this one as first require:

require(gen0Counter < CERATION_LIMIT_GEN0);

I would add a message so that you can see if that is the require that is failing, for instance:

require(gen0Counter < CERATION_LIMIT_GEN0m, "Gen 0 should be less than creation limit gen 0");

If this require fails, you will see the error message in the console.

1 Like

Thanks Dan-i, that actually was not the problem.
I spent all day trouble-shootingā€¦basically my code was a mess. I cleaned up my code, the interface statements, conflicting or improper emit events in the emit Transfer functions and just messy coding.
ā€¦itā€™s working now, thank you though.

Here it is:

kittyContract.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.3;

import "./IERC721.sol";

contract kittyContract is IERC721{

    string public constant tokenName = "MargaritaKitties";
    string public constant tokenSymbol = "MK";
    

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

    Kitty[] kitties;


    mapping(address => uint256) ownershipTokenCount;

    mapping (uint256 => address) public kittyIndexToOwner;


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

function totalSupply() external view override returns (uint256){
    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), "ERC721: invalid address");
    require (_to != address(this), "ERC721: cannot transfer to yourself");
    require (_owns(msg.sender,_tokenId), "ERC721: you do not own this 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);
}

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

Hi guys,

Iā€™m getting a bunch of error messages and have not seen them before. What am I doing wrong?

Schermafbeelding 2021-06-18 om 10.22.36

1 Like

Hey @thomascarl, hope you are ok.

You should read what the console is showing to you, apparently you just have some few typo errors.
46e830206d7da0539f2a5ce5c84ebf8433062cc4

If you still are having issues, please share your code in the following way so we can review it :nerd_face:
https://forum.ivanontech.com/t/faq-how-to-post-code-in-the-forum/35357/3

Carlos Z

SOLVED
I think iā€™ve had something wrong with my ownable file, some slight changes fixed the problem. But iā€™ll leave this messsage in here, in case someone else having the same issue.

Hi guys, iā€™m having this error. Any solutions ? I have tried via development and ganache. Same results both. I had to uncomment

development: {
    host: "127.0.0.1",     
    port: 7545,            
    network_id: "5777",      
    },

to connect the ganache, because somehow it stopped working after awhile. But my main issue is below. Attaching the token code just in case

Token Code

`pragma solidity ^0.5.0;

import ā€œ./IERC721.solā€;
import ā€œ./Ownable.solā€;

contract Kittycontract is IERC721, Ownable {

uint256 public constant CREATION_LIMIT_GEN0 = 10;
string public constant _name = "TolgaKitties";
string public constant _symbol = "TK";

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(uint256 => address) public kittyIndexToOwner; // token index to the address of its owner
mapping(address => uint256) ownershipTokenCount; // the amount of tokens an owner has

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), // Input perspective'den uint256 girmek daha basit, sonra convert et
        dadId: uint32(_dadId),
        generation: uint16(_generation)
    });  

    uint256 newKittenId = kitties.push(_kitty) - 1; // First cat will be ID 0
    
    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 (uint256 total){
    total = kitties.length;
}

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

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

function ownerOf(uint256 _tokenId) external view returns (address owner){        
    owner = kittyIndexToOwner[_tokenId]; 
    require(owner != address(0));       
} 

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); // Neden 2ye ayirmis -- _transfer fonksiyonunu daha cok yerde kullanacagiz.
} 

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

function _transfer(address _from, address _to, uint256 _tokenId) internal { // Internal cunku yukaridaki fonksiyondan otomatik olarak tetiklenecek, baskasi tetikleyemeyecek
    ownershipTokenCount[_to]++;
    
    kittyIndexToOwner[_tokenId] = _to;

    if (_from != address(0)) {  // Yeni kedi olusturunca _from adresi belirleyecegiz adress(0)yu ve oradan sahibine yollayacagiz
        ownershipTokenCount[_from]--;
    }
    emit Transfer(_from, _to, _tokenId);
}

}`

resim_2021-06-20_163209

Hi Carlos,

Iā€™ve solved almost all the errors except one. And that is this one below.

Schermafbeelding 2021-06-21 om 14.46.51

Iā€™ve researched it but I can not find the right way to bypass this error.

Down below my code:

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

import "./IERC721.sol";

 contract Kittycontract is IERC721 {

    string private constant name = "ThomasKitties";
    string private constant symbol = "TM";

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

    Kitty[] kitties;

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

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

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

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

    function transfer(address _to, uint256 _tokenId) external override {
        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{
        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;
    }
}
1 Like