- What is the time complexity of creating new cats? (constant or linear w nr of cats).
Constant 0(1), its just a one-off exectution. the function gets called and executes without no loops etc.
- What is the time complexity of the getAllCatsFor function? (constant or linear w nr of cats).
Linear 0(n), you have to iterate through the array to find the values
- How could the storage design be changed to make the getAllCats function constant? Implement your idea. Then discuss the benefits and drawbacks of your implementation and post everything in the forum.
Its easier to get the tokenids when introducing a mapping, however, I think in general both implementations works but the mapping implementation would be more gas-efficient. if weâre looping through the array with getAllCats it would require more gas than looping through the array when we need to delete a cat.
One thing i was thinking about tho, why not just get the last kitty with:
ownedKittys[_from][i] = ownedKittys[_from].length -1
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Kittycontract {
string public constant name = "TestKitties";
string public constant symbol = "TK";
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
event Birth(
address owner,
uint256 kittenId,
uint256 mumId,
uint256 dadId,
uint256 genes
);
struct Kitty {
uint256 genes;
uint64 birthTime;
uint32 mumId;
uint32 dadId;
uint16 generation;
}
struct Owners {
address owners;
uint tokenId;
}
Kitty[] kitties;
mapping (uint256 => address) public kittyIndexToOwner;
mapping(address => uint256[]) ownedKittys;
function ownersKittys(address _addressOwner) external view returns (uint[] memory)
{
return ownedKittys[_addressOwner];
}
function totalSupply() public view returns (uint) {
return kitties.length;
}
function ownerOf(uint256 _tokenId) external view returns (address)
{
return kittyIndexToOwner[_tokenId];
}
function transfer(address _to,uint256 _tokenId) external
{
require(_to != address(0));
require(_to != address(this));
require(_owns(msg.sender, _tokenId));
_transfer(msg.sender, _to, _tokenId);
}
function createKittyGen0(uint256 _genes) public returns (uint256) {
return _createKitty(0, 0, 0, _genes, msg.sender);
}
function _createKitty(
uint256 _mumId,
uint256 _dadId,
uint256 _generation,
uint256 _genes,
address _owner
) private returns (uint256) {
Kitty memory _kitty = Kitty({
genes: _genes,
birthTime: uint64(block.timestamp),
mumId: uint32(_mumId),
dadId: uint32(_dadId),
generation: uint16(_generation)
});
kitties.push(_kitty);
uint256 newKittenId = kitties.length - 1;
emit Birth(_owner, newKittenId, _mumId, _dadId, _genes);
_transfer(address(0), _owner, newKittenId);
return newKittenId;
}
function _transfer(address _from, address _to, uint256 _tokenId) internal {
require(_to != address(this), "cant send to yourself");
require(_to != address(0), "cant send to contract address");
kittyIndexToOwner[_tokenId] = _to;
ownedKittys[_to].push(_tokenId);
if (_from != address(0)) {
for (uint i = 0; i < ownedKittys[_from].length; i++) {
if(ownedKittys[_from][i] == _tokenId) {
ownedKittys[_from][i] = ownedKittys[_from].length -1;
ownedKittys[_from].pop();
}
}
}
emit Transfer(_from, _to, _tokenId);
}
function _owns(address _claimant, uint256 _tokenId) internal view returns (bool) {
return kittyIndexToOwner[_tokenId] == _claimant;
}
}