Hi there,
It is regarding function approve
I don’t see anywhere that topic and not sure if my code is correct and got couple of questions as well.
- I don’t understand that statement, could anyone explain please:
@dev The zero address indicates there is no approved address.
- We need to implement the following to the
function approve
:
// Throws unless `msg.sender` is the current NFT owner, or an authorized
// operator of the current owner.
not sure if my code is correct, could anyone confirm please
function approve(address _approved, uint256 _tokenId) external override {
if (doggieIndexToOwner[_tokenId] == msg.sender) {
doggieIndexToApprove[_tokenId] = _approved;
emit Approved(msg.sender, _approved, _tokenId)
}
else if (_operatorApprovals[msg.sender][_approved] == true) {
doggieIndexToApprove[_tokenId] = _approved;
emit Approved(msg.sender, _approved, _tokenId)
}
}
Edited:
I just realised that above code function is wrong but the below maybe too, please can someone comment on that:
function approve(address _approved, uint256 _tokenId) external override {
if (doggieIndexToOwner[_tokenId] == msg.sender) {
doggieIndexToApprove[_tokenId] = _approved;
emit Approved(msg.sender, _approved, _tokenId)
}
else if (_operatorApprovals[doggieIndexToOwner[_tokenId]][msg.sender] == true) {
doggieIndexToApprove[_tokenId] = _approved;
emit Approved(msg.sender, _approved, _tokenId)
}
}
full cryptodoggies.sol code
pragma solidity ^0.8.7;
import "./IERC721.sol";
import "./Ownable.sol";
contract DoggiesContract is IERC721, Ownable {
uint public constant CreationLimitGen0 = 30000;
string public constant override name = "Crypto Doggies";
string public constant override symbol = "CD";
event Birth(
address owner,
uint doggieId,
uint mumId,
uint dadId,
uint genes
);
struct Doggie{
uint256 genes;
uint64 birthTime;
uint32 mumId;
uint32 dadId;
uint16 generation;
}
Doggie[] doggies;
mapping (uint256 => address) public doggieIndexToOwner;
mapping (address => uint) ownershiptokenCount;
mapping (uint256 => address) public doggieIndexToApprove;
mapping (address => mapping(address => bool)) public _operatorApprovals;
uint public gen0Counter;
function getDoggie(uint _doggieId) external view returns(uint, uint64, uint32, uint32, uint16){
Doggie storage doggieToReturn = doggies[_doggieId];
return (
doggieToReturn.genes,
doggieToReturn.birthTime,
doggieToReturn.mumId,
doggieToReturn.dadId,
doggieToReturn.generation
);
}
function createDoggieGene0(uint _genes) public onlyOwner{
require(gen0Counter < CreationLimitGen0);
gen0Counter++;
_createDoggie(0, 0, 0, _genes, msg.sender);
}
function _createDoggie(
uint _mumId,
uint _dadId,
uint _generation,
uint _genes,
address _owner
)internal returns(uint) {
Doggie memory _doggie = Doggie({
genes: _genes,
birthTime: uint64(block.timestamp),
mumId: uint32(_mumId),
dadId: uint32(_dadId),
generation: uint16(_generation)
});
doggies.push(_doggie);
uint newDoggieId = doggies.length -1;
emit Birth(_owner, newDoggieId, _mumId, _dadId, _genes);
_transfer(address(0), _owner, newDoggieId);
return newDoggieId;
}
function balanceOf(address owner) external view override returns (uint256 balance) {
return ownershiptokenCount[owner];
}
function totalSupply() external view override returns (uint256 total){
return doggies.length;
}
function ownerOf(uint256 tokenId) external view override returns (address) {
return doggieIndexToOwner[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{
require(_to != address(0));
require(_to != address(this));
require(_owes(msg.sender, _tokenId));
_transfer(msg.sender, _to, _tokenId);
}
function _transfer(address _from, address _to, uint _tokenId) internal {
ownershiptokenCount[_to]++;
doggieIndexToOwner[_tokenId] = _to;
if(_from != address(0)){
ownershiptokenCount[_from]--;
delete doggieIndexToApprove[_tokenId]
}
emit Transfer(_from, _to, _tokenId);
}
function _owes(address _claimant, uint _tokenId) internal view returns(bool) {
doggieIndexToOwner[_tokenId] == _claimant;
}
/// @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) external override {
if (doggieIndexToOwner[_tokenId] == msg.sender) {
doggieIndexToApprove[_tokenId] = _approved;
emit Approved(msg.sender, _approved, _tokenId)
}
else if (_operatorApprovals[doggieIndexToOwner[_tokenId]][msg.sender] == true) {
doggieIndexToApprove[_tokenId] = _approved;
emit Approved(msg.sender, _approved, _tokenId)
}
}
//mapping (address => mapping(address => bool)) public _operatorApprovals;
//mapping (uint256 => address) public doggieIndexToApprove;
/// @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) external view returns (address) {
require(_tokenId < doggies.length);
return doggieIndexToApprove[_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) external {
require(_operator != msg.sender);
_operatorApprovals[msg.sender][_operator] = _approved;
emit ApprovalForAll(msg.sender, _operator, _approved);
}
/// @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) external view returns (bool){
return _operatorApprovals[_owner][_operator];
}
}