DEV Community

Abel Osaretin
Abel Osaretin

Posted on

EIP ERC721 Implementation

ERC 721 is different from ERC 20 token standard because it allows us to create a group of tokens that are uniquely different from each other. This feature allows NFTs to represent assets such as digital collectibles, physical properties, etc.

The ERC 721 standard has nine (9) functions, three (3) events, and one (1) interface.

First we create our state variables, mappings, and constructor.

State Variables


 // Token name
 string private _name;

 // Token symbol
 string private _symbol;

Enter fullscreen mode Exit fullscreen mode

Mappings


// To track the NFT (tokenId) and get the owner's address  
mapping(uint256 tokenId => address) private _ownersOf;

// To track the address to get the NFTs owned
mapping(address owner => uint256) private _balancesOf;

// To track approval of a particular NFT that other addresses can interact with.
mapping(uint256 tokenId => address) private _approvals;

// To grant approval for all the NFT in the address to another
mapping(address owner => mapping(address operator => bool)) private _IsApprovedForAll;

Enter fullscreen mode Exit fullscreen mode

Constructor

// Here we are setting the name and symbol for our collection
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}

Enter fullscreen mode Exit fullscreen mode

Functions

1. Balance Of:
This returns the number of NFTs owned by an address passed into _owner

Specification:

function balanceOf(address _owner) external view returns (uint256);
Enter fullscreen mode Exit fullscreen mode

Implementation:

function balanceOf(address owner) public view virtual returns (uint256) {

return _balancesOf[owner];

}
Enter fullscreen mode Exit fullscreen mode

2. Owner Of:
This returns the owner to an NFT

Specification:

function ownerOf(uint256 _tokenId) external view returns (address);
Enter fullscreen mode Exit fullscreen mode

Implementation:

function ownerOf(uint256 tokenId) public view virtual returns (address) {

return  owner = _ownerOf[tokenId];

}
Enter fullscreen mode Exit fullscreen mode

3. Set Approval For All:
Enable or disable approval for a third party ("operator") to manage all of msg.sender's assets

Specification:

function setApprovalForAll(address _operator, bool _approved) external;

Enter fullscreen mode Exit fullscreen mode

Implementation:

function setApprovalForAll(address operator, bool approved) external {

isApprovedForAll[msg.sender][operator] = approved;

emit ApprovalForAll(msg.sender, operator, approved);
}
Enter fullscreen mode Exit fullscreen mode

4. Approval:
Change or reaffirm the approved address for an NFT

Specification:

function approve(address _approved, uint256 _tokenId) external payable;

Enter fullscreen mode Exit fullscreen mode

Implementation:

function approve(address spender, uint id) external {

address owner = _ownerOf[id];

require(
msg.sender == owner || isApprovedForAll[owner][msg.sender],
"not authorized" );

_approvals[id] = spender;

emit Approval(owner, spender, id);

}

Enter fullscreen mode Exit fullscreen mode

5.Get Approval:
Get the approval on an address for a single NFT

Specification:

function getApproved(uint256 _tokenId) external view returns (address);

Enter fullscreen mode Exit fullscreen mode

Implementation:

function getApproved(uint id) external view returns (address) {

require(_ownerOf[id] != address(0), "token doesn't exist");

return _approvals[id];

}

Enter fullscreen mode Exit fullscreen mode

6. Approved or Owner:
if an address is an authorized operator owner and checks if _owner The address that owns the NFTs

Specification:

function isApprovedForAll(address _owner, address _operator) external view returns (bool);

Enter fullscreen mode Exit fullscreen mode

Implementation:

function isApprovedOrOwner(
address owner,
address spender,
uint id
) internal view returns (bool) {

return (spender == owner ||
isApprovedForAll[owner][spender] ||
spender == _approvals[id]);

}

Enter fullscreen mode Exit fullscreen mode

7. Transfer From:
Transfer ownership of an NFT

Specification:

function transferFrom(address _from, address _to, uint256 _tokenId) external payable;

Enter fullscreen mode Exit fullscreen mode

Implementation:

function transferFrom(address from, address to, uint id) public {

require(from == _ownerOf[id], "from != owner");

require(to != address(0), "transfer to zero address");

require(_isApprovedOrOwner(from, msg.sender, id), "not authorized");

_balanceOf[from]--;

 _balanceOf[to]++;

 _ownerOf[id] = to;

 delete _approvals[id];

 emit Transfer(from, to, id);

 }

Enter fullscreen mode Exit fullscreen mode

8. Safe Tranfer From Address to Address:
Transfers the ownership of an NFT from one address to another address
Specification:

function safeTransferFrom(address _from, address _to, uint256 _tokenId) external payable;

Enter fullscreen mode Exit fullscreen mode

Implementation:

function safeTransferFrom(address from, address to, uint id) external {

transferFrom(from, to, id);

require(

to.code.length == 0 ||
                IERC721Receiver(to).onERC721Received(msg.sender, from, id, "") ==
                IERC721Receiver.onERC721Received.selector,
"unsafe recipient" );

}

Enter fullscreen mode Exit fullscreen mode

9. Safe Transfer From Address to Contract:
Transfers the ownership of an NFT from one address to contract address.

Specification:

function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes data) external payable;
Enter fullscreen mode Exit fullscreen mode

Implementation:

function safeTransferFrom(
address from,
address to,
uint id,
bytes calldata data
) external {

transferFrom(from, to, id);

require(

to.code.length == 0 ||
                IERC721Receiver(to).onERC721Received(msg.sender, from, id, data) ==
                IERC721Receiver.onERC721Received.selector,
"unsafe recipient"

);
}
Enter fullscreen mode Exit fullscreen mode

Top comments (0)