개발일지/블록체인

ERC721을 사용한 NFT 코드 이해

자코린이 2022. 1. 5. 20:00

여기서 4개의 장부가 중요하다.(mapping)

_tokenOwner 는 토큰아이디로 그 토큰 주인의 주소를 적는 장부이다.

_tokenApprovals 는 토큰 아이디로 그 토큰을 허용받은 주소를 적는 장부이다.

_ownerTokenCount 는 주소가 소유한 토큰의 개수를 적는 장부이다.(그냥 알고리즘을 사용할 수 있지만, 가스비를 생각해 장부로 만든다.)

_operatorApprovals 는 소유자가 다른 사람에게 권한을 승인한 여부를 적는 장부이다.

 

여기서 중요하다고 생각하는 장부는 _tokenOwner와 _ownerTokenCount가 중요하다고 생각한다.

그 이유는 중요한 함수인 mint(생성), safeTransferFrom(안전한 주소 변경), transferFrom(실재 주소 변경), balanceOf(토큰 개수) 에서 이 2개의 장부를 사용하기 때문이다.

function _mint(address to, uint256 tokenId) internal {
require(to != address(0), "ERC721: mint to the zero address");
require(!_exists(tokenId), "ERC721: token already minted");
_tokenOwner[tokenId] = to;
_ownedTokensCount[to].increment();
emit Transfer(address(0), to, tokenId);
}
 
이 함수는 tokenId 로 만들어서 주는 주소(to)로 장부에 적고, 그 장부의 갯수를 1개 늘린다.
address(0)(실행자 자신) 에서 그 주소로 토큰을 보냈다고 이벤트로 기록한다. 
 

 

function safeTransferFrom(address from, address to, uint256 tokenId) public {
safeTransferFrom(from, to, tokenId, "");
}
 
function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public {
transferFrom(from, to, tokenId);
require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
}

function transferFrom(address from, address to, uint256 tokenId) public {

//solhint-disable-next-line max-line-length
require(_isApprovedOrOwner(msg.sender, tokenId), "ERC721: transfer caller is not owner nor approved");
 
_transferFrom(from, to, tokenId);
}
function _transferFrom(address from, address to, uint256 tokenId) internal {
require(ownerOf(tokenId) == from, "ERC721: transfer of token that is not own");
require(to != address(0), "ERC721: transfer to the zero address");
_clearApproval(tokenId);
_ownedTokensCount[from].decrement();
_ownedTokensCount[to].increment();
_tokenOwner[tokenId] = to;
emit Transfer(from, to, tokenId);
}

위의 2 함수는  대상의 주소가 컨트랙트인지 확인 (_checkOnERC721Received)후 transferFrom함수를 호출한다.

transferFrom함수는 보내는 토큰 주인의 주소가 보내는 사람의 주소와 같은지 확인(_isApprovedOrOwner)한 후 

 _transferFrom함수를 호출한다.

_transferFrom함수는 허용된 권한을 삭제하고 보내는 사람의 갯수를 1개 줄이고, 받은 사람의 갯수는 1개 늘린다. 그 후 그 토큰의 주인을 받은 사람의 주소로 바꾼 후 그 이벤트를 블록체인에 기록한다.

function balanceOf(address owner) public view returns (uint256) {
require(owner != address(0), "ERC721: balance query for the zero address");
return _ownedTokensCount[owner].current();
}
 

balanceO함수는 인수에 넣어진 주소의 토큰 갯수를 반환하는 함수이다.

 

이 3개 종류의 함수와 4개의 장부가 가장 중요한 메소드와 필드라고 생각한다.

                    *아직 공부 중인 학생입니다. 틀린 부분이 있을 수 있으니 틀린부분은 탯글로 적어주시면 그 부분은 수정하겠습니다.*