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